Skip to content

perf: resolve stale-file last-touch with one git walk - #203

Merged
stephenc222 merged 1 commit into
mainfrom
fix/last-touch-single-walk
Sep 22, 2026
Merged

stephenc222 merged 1 commit into
mainfrom
fix/last-touch-single-walk

Conversation

@stephenc222

Copy link
Copy Markdown
Contributor

Summary

  • Implements hotspots-research/docs/promotion-briefs/last-touch-single-walk.md.
  • git.rs::batch_last_touch_for_files resolved days_since_last_change for files with no commit in the 30-day window by running one full-history, path-limited git log -- <500 paths> per 500 files. Each call walks the whole history, so --touch-mode file cost grew with history length times stale files: 232s on vscode, of which the fallback is essentially all (the 30-day window query itself takes 0.01s).
  • Replaced with one unrestricted git log --format="COMMIT %ct" --name-only --until=<as_of> walk. Signature and value semantics unchanged.
  • Measured (research POC): vscode 397.6s -> 6.1s (~65x), scikit-learn 14.4s -> 0.8s (18x) for the fallback alone.

Behavior note (intended)

The old path-limited walk applies git history simplification, which can prune a side-branch commit at a merge that is TREESAME to the first parent. The single walk sees those commits, so a value is never older than before and is occasionally more recent. In the vscode POC 28 of 14,247 stale files differed (0.2%): 23 strictly more recent, 5 within a day, 0 older. On linear history the results are identical. A fixture test documents the difference.

Test plan

  • Linear-history fixture: new map equals a test-only copy of the old chunked implementation exactly, with expected day values asserted
  • Merge fixture (-s ours): new never older than old; f.txt old 10 days, new 8
  • Commits after as_of ignored; files absent from history omitted; empty input spawns no git
  • cargo test --workspace (555 in hotspots-core), cargo fmt --check, cargo clippy --workspace --all-targets clean
  • Old (v1.40.0) vs new binary on real repos, --touch-mode file: days_since_last_change identical for every function on this repo (982), scikit-learn (3,826) and vite (2,102), none larger; wall time 2.2s->1.6s, 9.3s->4.9s, 2.2s->1.0s

Not in scope

  • git quotes non-ASCII paths (core.quotePath), so such files never match stale_files in either method. Noted in the brief as a separate change.

🤖 Generated with Claude Code

…0 files

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@stephenc222
stephenc222 merged commit 492f767 into main Sep 22, 2026
7 checks passed
@stephenc222
stephenc222 deleted the fix/last-touch-single-walk branch September 22, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant