Detect file renames in review diffs#3916
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR fundamentally changes how working tree review diffs are computed, replacing per-file untracked diff generation with a temporary index-based approach. This is a significant architectural change to core diff logic that affects the review workflow and warrants human review. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ac42fc27c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0fc42d5. Configure here.
| cwd, | ||
| ["add", "--intent-to-add", "-A", "--", "."], | ||
| { env }, | ||
| ); |
There was a problem hiding this comment.
add -A erases index-only changes
High Severity
The readWorkingTreeReviewDiff function's git add --intent-to-add -A command on the temporary index re-adds files that were git rm --cached but still exist in the working tree. This causes the working-tree review diff to incorrectly omit staged deletions and other staged-only index changes.
Reviewed by Cursor Bugbot for commit 0fc42d5. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0fc42d53cc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| yield* executeGit( | ||
| "GitVcsDriver.readWorkingTreeReviewDiff.add", | ||
| cwd, | ||
| ["add", "--intent-to-add", "-A", "--", "."], |
There was a problem hiding this comment.
Preserve non-ignored index-only deletions
Here git add -h says -A adds changes from tracked and untracked files and -N records only the fact a path will be added, so this temp-index refresh no longer preserves an existing index-only deletion when the same path remains as a non-ignored untracked file. Fresh evidence beyond the prior ignored-file case: after git rm --cached f without adding f to .gitignore, this command turns the copied index into DA f, and the following git diff HEAD is empty if the file still matches HEAD (or shows a modification if it changed), whereas the real index represents a deletion to be committed; the review preview can therefore miss or misstate files being untracked.
Useful? React with 👍 / 👎.
| yield* executeGit( | ||
| "GitVcsDriver.readWorkingTreeReviewDiff.add", | ||
| cwd, | ||
| ["add", "--intent-to-add", "-A", "--", "."], |
There was a problem hiding this comment.
Keep tracked diffs when untracked repos cannot be added
Because git add -h confirms -A scans untracked files too, this command can fail before the diff is generated for an otherwise valid dirty worktree; for example, an untracked nested Git repository with no commit makes git add --intent-to-add -A -- . exit 128 (does not have a commit checked out). Since the caller converts any readWorkingTreeReviewDiff failure into an empty working-tree preview, the presence of that scratch nested repo hides unrelated tracked modifications that the old tracked git diff HEAD -- path still reported.
Useful? React with 👍 / 👎.


Verification
1. File rename with no changes
Git detects one rename and the viewer renders a single
exact-original.ts → exact-renamed.tsentry with-0 +0and no content hunk.2. File rename with minimal changes
Git detects an 84% similar rename, so the viewer keeps one
minimal-original.ts → minimal-renamed.tsentry and renders the-1 +1content diff.3. File rename with too many changes
The files are below Git's rename-similarity threshold, so the viewer correctly renders
replaced-new.tsas an addition andreplaced-original.tsas a deletion.Summary
Root cause
Working-tree previews generated tracked and untracked patches separately. A normal filesystem rename therefore appeared as an unrelated deletion and addition because Git never saw both paths in the same comparison.
Impact
The diff viewer now renders qualifying file moves as one renamed file while still showing any content changes. Branch comparisons use the same explicit Git rename detection.
Validation
pnpm exec vp test apps/server/src/vcs/GitVcsDriverCore.test.ts(27 tests)pnpm exec vp checkpnpm exec vp run typecheckgit diff --checkNote
Detect file renames in working-tree and branch-range review diffs
git diff --no-indexper untracked file) with a single unified diff via the newreadWorkingTreeReviewDifffunction in GitVcsDriverCore.ts.--find-renamesand--minimalagainst HEAD (or an empty tree when no commits exist yet).--find-renamesto the branch-range diff so committed renames are also detected./dev/nulldiff approach is removed.Macroscope summarized ca811f5.
Note
Medium Risk
Changes how review diffs are produced (temp index + intent-to-add staging); behavior shifts for untracked files, renames, and edge cases, though the real index is isolated and covered by new integration tests.
Overview
Review diff previews now build the dirty worktree patch in one Git comparison instead of merging
git diff HEADwith per-untrackedgit diff --no-indexoutput.readWorkingTreeReviewDiffcopies the real index into a tempGIT_INDEX_FILE, runsgit add --intent-to-add -A, and diffs againstHEAD(or an empty tree before the first commit) with--find-renamesand--minimal, without touching the user's index. Branch-range previews get the same--find-renamesflag onbaseRef...HEAD.Integration tests cover pre-first-commit untracked/staged files, unstaged and committed renames with edits, sparse-checkout scope, and staged index-only deletions.
Reviewed by Cursor Bugbot for commit ca811f5. Bugbot is set up for automated code reviews on this repo. Configure here.