fix(host-service): list an intent-to-add rename once in git status

Merged
SA
1mo ago
+30-2

What broke

A user report: the desktop app showed "This view hit an error" as soon as a workspace opened, on every launch.

The Changes list had the same unstaged path twice. Opening the diff pane then threw CodeView.addItem: duplicate id "diff:unstaged:<path>". The diff pane is restored on launch and the git state is on disk, so the same workspace failed again every time.

Why

detectUnstagedRenames copies the index, marks untracked files intent-to-add, and diffs the whole worktree. It returned every rename in that diff. When the real index already has an intent-to-add file that git pairs with a deletion (git status shows R old -> new), that rename is already in unstaged. It came back a second time whenever the worktree also had any unrelated deletion and any untracked file. The merge in git-status.ts only drops consumed deleted/untracked entries, so the renamed entry was pushed twice.

Fix

Keep only renames onto the paths the detection marked itself.

Verification

  • New integration test: an intent-to-add rename + an unrelated deletion + an untracked file gives one renamed row. It fails on main (new.txt twice) and passes here.
  • Dev app over CDP, same git state: before the fix, two rows and the error screen, and both Reload and reopening the workspace fail again. After the fix, one row, the diff pane opens, and it still opens after a reload.
  • git/utils tests: long converging sequence of mixed batches times out at 5 s on this machine on main as well; with --timeout 60000 that file passes 39/39 with and without this change.

Not in this PR: the per-pane error boundary that would stop one pane's throw from taking over the workspace.


Summary by cubic

Fixes a workspace crash loop by listing an intent-to-add rename once in git status instead of twice. The duplicate unstaged path made the restored diff pane throw on the duplicate id, so the same workspace failed on every launch.

detectUnstagedRenames copied the index, marked untracked files intent-to-add, and diffed the whole worktree, so it also returned renames git already reported for files intent-to-add in the real index. It now only returns renames onto the files it marked itself.

Bug Fixes

  • Added an integration test with an intent-to-add rename, an unrelated deletion, and an untracked file that asserts the rename appears once.

Summary by CodeRabbit

  • Bug Fixes
    • Git status now reports renames involving untracked files without duplicating rename entries already detected by Git.
    • Files marked for addition and modified before staging are correctly included in rename detection.
  • Tests
    • Added coverage for rename detection alongside deleted tracked files and other untracked files.