Describe the bug
workspace.git.cli(["status", "--short"]) (and --porcelain / --porcelain=v2, and the worker-shell git command) reports a fully staged deletion with worktree code D, producing DD <path>. In porcelain v1, DD specifically means an unmerged "both deleted" merge conflict; in porcelain v2, DD on a 1 line is not a producible state at all (unmerged entries use u lines).
Cause: packages/computer/src/git/status.ts:111, first branch of worktreeCode:
if (workdir === 0 && stage === 0 && head === 1) return "D";
For the status-matrix row [path, 1, 0, 0] (present in HEAD, absent from workdir, absent from index) the workdir matches the index (the deletion is fully staged), so Y (workdir vs index) must be a space. The rendered forms come out of formatShort / formatPorcelainV1 (status.ts:152-173) and formatPorcelainV2 (status.ts:127-144).
The existing suite covers D (worktree delete, unstaged) but never the staged-deletion row [path,1,0,0].
Expected behavior
Real git, for git rm f && git status --porcelain: D f (X=D, Y=space).
Steps to reproduce
Same harness as packages/computer/src/git/status.test.ts: commit gone.txt, unlink it from the worktree, stage the deletion via the package's own git add -A path (addWith({ all: true }) in staging.ts), then run statusWith. Actual output:
statusMatrix: [["gone.txt",1,0,0]] <- in HEAD, absent workdir, absent index
entries: [{"path":"gone.txt","index":"D","worktree":"D"}]
short: "DD gone.txt\n"
v1: "DD gone.txt\n"
v2: "1 DD gone.txt\n"
Expected: "D gone.txt\n" and {index:"D", worktree:" "}.
Impact
Any staged deletion (git rm, git add -A after a delete, commit -a flows) is misreported to porcelain parsers and to agents reading git status as a merge conflict. An agent driving the workspace via the shell backend will try to "resolve" conflicts that don't exist.
Proposed fix
In worktreeCode, the head === 1 && workdir === 0 && stage === 0 row should return " ", leaving the second branch (workdir === 0 && stage > 0, deletion not yet staged) as the only producer of Y=D. One-line change; add a matrix-row test for [p,1,0,0] asserting {index:"D", worktree:" "}.
Environment
cloudflare/computer at 76d9e75 (current main), local checkout
npx vitest run baseline in packages/computer: 897/897 pass before adding the repro
- Node v22.18.0, Windows 11 (platform-independent)
Describe the bug
workspace.git.cli(["status", "--short"])(and--porcelain/--porcelain=v2, and the worker-shellgitcommand) reports a fully staged deletion with worktree codeD, producingDD <path>. In porcelain v1,DDspecifically means an unmerged "both deleted" merge conflict; in porcelain v2,DDon a1line is not a producible state at all (unmerged entries useulines).Cause:
packages/computer/src/git/status.ts:111, first branch ofworktreeCode:For the status-matrix row
[path, 1, 0, 0](present in HEAD, absent from workdir, absent from index) the workdir matches the index (the deletion is fully staged), so Y (workdir vs index) must be a space. The rendered forms come out offormatShort/formatPorcelainV1(status.ts:152-173) andformatPorcelainV2(status.ts:127-144).The existing suite covers
D(worktree delete, unstaged) but never the staged-deletion row[path,1,0,0].Expected behavior
Real git, for
git rm f && git status --porcelain:D f(X=D, Y=space).Steps to reproduce
Same harness as
packages/computer/src/git/status.test.ts: commitgone.txt,unlinkit from the worktree, stage the deletion via the package's owngit add -Apath (addWith({ all: true })instaging.ts), then runstatusWith. Actual output:Expected:
"D gone.txt\n"and{index:"D", worktree:" "}.Impact
Any staged deletion (
git rm,git add -Aafter a delete,commit -aflows) is misreported to porcelain parsers and to agents readinggit statusas a merge conflict. An agent driving the workspace via the shell backend will try to "resolve" conflicts that don't exist.Proposed fix
In
worktreeCode, thehead === 1 && workdir === 0 && stage === 0row should return" ", leaving the second branch (workdir === 0 && stage > 0, deletion not yet staged) as the only producer of Y=D. One-line change; add a matrix-row test for[p,1,0,0]asserting{index:"D", worktree:" "}.Environment
cloudflare/computerat76d9e75(currentmain), local checkoutnpx vitest runbaseline inpackages/computer: 897/897 pass before adding the repro