Skip to content

fix: use git blame -C to prevent misattribution of shifted lines in git ai diff#984

Merged
svarlamov merged 2 commits intomainfrom
fix/diff-detect-copies-misattribution
Apr 7, 2026
Merged

fix: use git blame -C to prevent misattribution of shifted lines in git ai diff#984
svarlamov merged 2 commits intomainfrom
fix/diff-detect-copies-misattribution

Conversation

@svarlamov
Copy link
Copy Markdown
Member

@svarlamov svarlamov commented Apr 6, 2026

Summary

  • blame_hunks_for_ranges in src/commands/blame.rs now translates detect_copies/detect_moves on GitAiBlameOptions into -C/-M flags on the git-blame command line.
  • apply_blame_for_side in src/commands/diff.rs already set detect_copies: 1, but the field was never wired through to the actual git invocation — the fix was inert (caught by Devin review).
  • Adds a regression test test_diff_blame_uses_detect_copies_for_moved_ai_lines that fails on the broken code and passes with the fix.

Root cause

When a commit moves a substantial block of lines to a different position within a file (e.g. reordering functions), Myers diff represents the moved block as explicit + lines. Those lines end up in apply_blame_for_side's added_lines set. Without -C (which implies -M), git blame attributes them to the current commit rather than the original one — so they fall through as Human when the current commit has no attestation covering them. With -C, git blame detects the within-file move and correctly traces the lines back to the originating commit.

Observed on commit 7b99854f (100% AI-authored): git ai diff showed 4 lines attributed to Human because git blame without -C placed them in the current commit rather than parent 6ff95531 where the covering attestation lived.

Regression test

test_diff_blame_uses_detect_copies_for_moved_ai_lines:

  1. Commit A — AI writes func_one (6 lines) + func_two (6 lines), both fully AI-attested.
  2. Commit B — AI adds new_func (attested in B) and func_one shifts to the end. Myers diff represents func_one as + lines at its new position.
  3. Without -C: git blame says the moved func_one lines were introduced in B → no attestation in B → Human ❌
  4. With -C: git blame traces them back to A → A's attestation covers them → AI ✓

Test plan

  • cargo test --test integration -- diff — all 201 tests pass (1 new test added)
  • The failing ubuntu wrapper-daemon CI check is test_search_by_commit_range_in_worktree — a daemon sync timeout unrelated to this change; the same test passes on ubuntu wrapper and ubuntu daemon modes.

…on of shifted lines

When git diff absorbs shifted pre-existing lines into a replacement hunk (e.g.
a comment deletion adjacent to a large addition), those lines appear as `+` in
the diff. Without `-C`, git blame attributes them to the current commit rather
than the originating one, causing false Human attribution for AI-written lines.

Setting `detect_copies: 1` enables `-C` so git blame detects within-commit line
movement and correctly traces the lines back to their originating commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

… test

blame_hunks_for_ranges read GitAiBlameOptions.detect_copies but never
translated it into -C flags on the git-blame command line, making the
detect_copies: 1 set in apply_blame_for_side entirely inert.

Add the translation (and the parallel -M path for detect_moves) so that
git blame actually receives -C/-M when requested.

Add test_diff_blame_uses_detect_copies_for_moved_ai_lines which:
- Creates commit A where an AI writes func_one and func_two.
- Creates commit B where the AI adds new_func and func_one is moved to
  the end (Myers diff represents this as explicit + lines, not context).
- Without -C git blame attributes the moved func_one lines to B (which
  has no attestation for them) → wrongly shown as Human.
- With -C git blame traces them back to A's attestation → correctly AI.

The test is verified to fail on the un-fixed code and pass with the fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@svarlamov svarlamov merged commit 7213863 into main Apr 7, 2026
25 of 26 checks passed
@svarlamov svarlamov deleted the fix/diff-detect-copies-misattribution branch April 7, 2026 01:53
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