Skip to content

Commit 68baf02

Browse files
committed
Add bin/git-history-matching
1 parent 9792eda commit 68baf02

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

bin/git-history-matching

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
3+
import subprocess
4+
import re
5+
import argparse
6+
from datetime import datetime, timedelta
7+
8+
9+
def _parse_args() -> argparse.Namespace:
10+
parser = argparse.ArgumentParser(
11+
description="Count commits with messages matching a regex in a given date range."
12+
)
13+
parser.add_argument(
14+
"--start_date", type=str, help="Start date (YYYY-MM-DD)", required=True
15+
)
16+
parser.add_argument(
17+
"--end_date", type=str, help="End date (YYYY-MM-DD)", required=True
18+
)
19+
parser.add_argument(
20+
"--pattern",
21+
type=str,
22+
help="Regex pattern to match commit messages",
23+
required=False,
24+
default="*",
25+
)
26+
return parser.parse_args()
27+
28+
29+
def _get_commit_messages(
30+
start_date: str,
31+
end_date: str,
32+
regex_pattern: str,
33+
) -> dict[str, list[str]]:
34+
start = datetime.strptime(start_date, "%Y-%m-%d")
35+
end = datetime.strptime(end_date, "%Y-%m-%d")
36+
pattern = re.compile(regex_pattern)
37+
38+
dates = {}
39+
current_date = start
40+
while current_date <= end:
41+
next_date = current_date + timedelta(days=1)
42+
current_date_str = current_date.strftime("%Y-%m-%d")
43+
next_date_str = next_date.strftime("%Y-%m-%d")
44+
match_count = 0
45+
46+
try:
47+
log_output = subprocess.check_output(
48+
[
49+
"git",
50+
"log",
51+
"--pretty=format:%s",
52+
"--date=format:%Y-%m-%d",
53+
"--since",
54+
current_date_str,
55+
"--until",
56+
next_date_str,
57+
],
58+
text=True,
59+
)
60+
messages = log_output.strip().split("\n") or []
61+
match_count = sum(1 for message in messages if pattern.search(message))
62+
except subprocess.CalledProcessError as e:
63+
print(
64+
f"Error fetching git log for {current_date_str}: {e}"
65+
)
66+
dates[current_date_str] = match_count
67+
current_date = next_date
68+
return dates
69+
70+
71+
def _main():
72+
args = _parse_args()
73+
commit_messages = _get_commit_messages(
74+
start_date=args.start_date,
75+
end_date=args.end_date,
76+
regex_pattern=args.pattern,
77+
)
78+
79+
print("date, count")
80+
for k, v in commit_messages.items():
81+
print(f"{k}, {v}")
82+
83+
84+
if __name__ == "__main__":
85+
_main()

0 commit comments

Comments
 (0)