Skip to content

Commit 50d1fa8

Browse files
committed
feat: add script to generate git log sorted by author date
1 parent 94b63b1 commit 50d1fa8

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

scripts/git_log_by_commit_date.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env python3
2+
"""Generate a git log sorted by author (commit) date.
3+
4+
Outputs a tab-delimited file with:
5+
commit_hash, author_date, committer_date, author_name, author_email, subject
6+
7+
Usage:
8+
./scripts/git_log_by_commit_date.py
9+
./scripts/git_log_by_commit_date.py --output git-log-by-commit-date.tsv
10+
./scripts/git_log_by_commit_date.py --repo /path/to/repo --output git-log-by-commit-date.tsv
11+
"""
12+
from __future__ import annotations
13+
14+
import argparse
15+
import datetime
16+
import subprocess
17+
from pathlib import Path
18+
19+
20+
def format_ts(ts: int) -> str:
21+
return datetime.datetime.fromtimestamp(ts).astimezone().strftime("%Y-%m-%dT%H:%M:%S%z")
22+
23+
24+
def build_log(repo: Path) -> list[str]:
25+
log = subprocess.check_output(
26+
[
27+
"git",
28+
"-C",
29+
str(repo),
30+
"log",
31+
"--pretty=format:%h\t%at\t%ct\t%an\t%ae\t%s",
32+
],
33+
text=True,
34+
)
35+
36+
rows: list[tuple[int, str, int, str, str, str]] = []
37+
for line in log.splitlines():
38+
parts = line.split("\t", 5)
39+
if len(parts) < 6:
40+
continue
41+
commit_hash, author_ts, committer_ts, author_name, author_email, subject = parts
42+
try:
43+
author_ts_i = int(author_ts)
44+
committer_ts_i = int(committer_ts)
45+
except ValueError:
46+
continue
47+
rows.append((author_ts_i, commit_hash, committer_ts_i, author_name, author_email, subject))
48+
49+
rows.sort(key=lambda row: row[0], reverse=True)
50+
51+
output: list[str] = [
52+
"commit_hash\tauthor_date\tcommitter_date\tauthor_name\tauthor_email\tsubject"
53+
]
54+
for author_ts_i, commit_hash, committer_ts_i, author_name, author_email, subject in rows:
55+
output.append(
56+
"\t".join(
57+
[
58+
commit_hash,
59+
format_ts(author_ts_i),
60+
format_ts(committer_ts_i),
61+
author_name,
62+
f"<{author_email}>",
63+
subject,
64+
]
65+
)
66+
)
67+
68+
return output
69+
70+
71+
def main() -> None:
72+
parser = argparse.ArgumentParser(description="Write git log sorted by author date.")
73+
parser.add_argument(
74+
"--repo",
75+
type=Path,
76+
default=Path.cwd(),
77+
help="Path to the git repository (default: current directory)",
78+
)
79+
parser.add_argument(
80+
"--output",
81+
type=Path,
82+
default=Path("git-log-by-commit-date.tsv"),
83+
help="Output file path (default: git-log-by-commit-date.tsv)",
84+
)
85+
args = parser.parse_args()
86+
87+
lines = build_log(args.repo)
88+
args.output.write_text("\n".join(lines) + "\n")
89+
90+
91+
if __name__ == "__main__":
92+
main()

0 commit comments

Comments
 (0)