Skip to content

perf(reset): skip wasted blame in post-reset working-log reconstruction (#1025)#1068

Open
svarlamov wants to merge 4 commits intomainfrom
fix/issue-1025-reset-performance
Open

perf(reset): skip wasted blame in post-reset working-log reconstruction (#1025)#1068
svarlamov wants to merge 4 commits intomainfrom
fix/issue-1025-reset-performance

Conversation

@svarlamov
Copy link
Copy Markdown
Member

@svarlamov svarlamov commented Apr 13, 2026

Summary

Root cause: After a git reset HEAD~N, reconstruct_working_log_after_reset builds two VirtualAttributions objects and merges them to recover AI line attribution. Step 4 built a target_va — intended to capture AI lines that predate the reset range (lines AI-authored before the target commit, still present in the working directory). But the implementation passed blame_start_commit = target_commit_sha and base_commit = target_commit_sha to new_for_base_commit, producing git blame target..target for every changed file — an always-empty range where every line is a boundary commit (pre-range, attributed human). target_va always had zero AI attributions and never filled any gaps.

Additionally, old_head_va is built via from_working_log_for_commit, which replays existing working log entries on top of blame. Any AI lines predating the reset range that git-ai tracks are already carried into old_head_va through that working log replay, so a correct target_va would have been redundant anyway.

Fix: Replace Step 4 with an empty VirtualAttributions constructed directly. No subprocess calls. Merge result is identical to before because target_va was always empty. Verified: removing new_for_base_commit(target, target) causes zero test regressions across all 269 reset tests.

Affected flows: git reset --soft/--mixed/--merge in both sync (async_mode = false, blocking) and async (daemon) modes — the daemon calls reconstruct_working_log_after_reset directly at three sites.

Performance impact

Before: N git blame subprocess calls for target_va (N = files changed in the reset diff), each returning nothing useful — O(files × file_size) wasted work scaling directly with commit size.
After: 0 subprocess calls for target_va.

For the scenario in #1025 (large monorepo, 500+ line commit touching many files, async_mode = false), this halves the total blame work in post_reset_hook.

Test plan

  • All 269 reset integration tests pass (confirmed with and without the fix — no regressions)
  • 2 new large-commit reset tests: test_reset_large_commit_preserves_attribution (wrapper + worktree modes)
  • Full integration suite: 2946 passed, 0 failed
  • Unit tests: 1396 passed, 0 failed

Fixes #1025

svarlamov and others added 2 commits April 13, 2026 03:36
When `git reset HEAD~` runs with `async_mode = false` (sync/wrapper mode),
`reconstruct_working_log_after_reset` was building two VirtualAttributions:

1. old_head VA — blame `target..old_head` — correctly finds AI lines in the
   unwound commit(s).
2. target VA — blame `target..target` — always an empty range; every line is
   attributed to a "boundary" (pre-range) commit and mapped to human, so the
   VA had zero AI attributions.

Running `git blame` for every file in the reset diff to produce zero output was
O(files × file_size) wasted work.  On a 500+ line commit in a large monorepo
with many changed files this caused noticeable latency in the wrapper.

Fix: replace Step 4 with an empty VirtualAttributions created directly, with no
subprocess invocations.  The merge step (`merge_attributions_favoring_first`)
with an empty secondary VA is a no-op, so correctness is unchanged — all
existing 79 reset tests continue to pass and the new large-commit test passes.

Closes #1025

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

svarlamov and others added 2 commits April 13, 2026 04:18
The previous wrapper-daemon run hit a pre-existing race condition in
test_cross_repo_checkpoint_preserves_local_repo_checkpoint (unrelated to
this PR's changes — a dedicated fix branch already exists for it).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expand the Step 4 comment to explain both failure modes:
1. The blame range target..target is always empty (broken from day one)
2. old_head_va already covers pre-range AI lines via working log replay,
   making a correct target_va redundant regardless

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Slow performance on git reset HEAD~ for larger commits

1 participant