Implement `commitlens hotspots [--top N]` — files ranked by how often they appear in commits.
Deliverable
Module: `src/commitlens/hotspots.py`. Register in `_register_subcommands`.
CLI args: `--top N` (default 20). `--ext .py,.ts` filter optional; if you skip it, leave a TODO comment but don't add the flag — keep scope tight.
Output schema
```json
{
"_render": "",
"hotspots": [
{"path": "src/foo.py", "commits": 42, "authors": 5, "last_commit": "2026-04-29T18:30:00+00:00"},
...
],
"total_commits": 213
}
```
`commits` is the count of commits that touched the file (added/modified/deleted/renamed all count). `authors` is the distinct author email count for those commits. `last_commit` is the most recent commit-time ISO that touched it.
Human render
Fixed-width table sorted by commits desc. Columns: path (truncate to 60), commits, authors, last (relative — "3d ago", "2w ago", "4mo ago"). Cap to `--top`.
Data source
`git log --name-only --pretty=format:%H|%aI|%ae` parsed in Python. (`--numstat` gives lines too if needed, but we don't need them for v1.)
Renames: pass `--follow` is per-file and slow on large repos — for v1, treat the post-rename path as a fresh file. The issue description should explicitly call this out as a known limitation in a comment.
Tests
`tests/test_hotspots.py` using `git_repo`. Build:
- one file changed in 5 commits by 2 authors (high hotspot)
- one file changed in 1 commit (low hotspot)
- one binary file (should still count as touched)
- one rename (treated as new path)
Assert ordering, counts, distinct-author counting, last_commit correctness.
Implement `commitlens hotspots [--top N]` — files ranked by how often they appear in commits.
Deliverable
Module: `src/commitlens/hotspots.py`. Register in `_register_subcommands`.
CLI args: `--top N` (default 20). `--ext .py,.ts` filter optional; if you skip it, leave a TODO comment but don't add the flag — keep scope tight.
Output schema
```json
{
"_render": "",
"hotspots": [
{"path": "src/foo.py", "commits": 42, "authors": 5, "last_commit": "2026-04-29T18:30:00+00:00"},
...
],
"total_commits": 213
}
```
`commits` is the count of commits that touched the file (added/modified/deleted/renamed all count). `authors` is the distinct author email count for those commits. `last_commit` is the most recent commit-time ISO that touched it.
Human render
Fixed-width table sorted by commits desc. Columns: path (truncate to 60), commits, authors, last (relative — "3d ago", "2w ago", "4mo ago"). Cap to `--top`.
Data source
`git log --name-only --pretty=format:%H|%aI|%ae` parsed in Python. (`--numstat` gives lines too if needed, but we don't need them for v1.)
Renames: pass `--follow` is per-file and slow on large repos — for v1, treat the post-rename path as a fresh file. The issue description should explicitly call this out as a known limitation in a comment.
Tests
`tests/test_hotspots.py` using `git_repo`. Build:
Assert ordering, counts, distinct-author counting, last_commit correctness.