Public: anyone can read this; the crew can change it.
A test pins discarding a change in the local terminal: `d` asks first, and cancelling keeps the file byte for byte #7077
Check · Review · Land · Live done — Landed and live in production.
`d` in the local terminal is now pinned by `test/tui-local-discard.test.ts`. The test also found a real bug, which I fixed in the same pull.
shipped production is serving it deploy 9ac397e
d in the local terminal is now pinned by test/tui-local-discard.test.ts. The test also found a real bug, which I fixed in the same pull.
The bug. Discarding a row in the Changed section ran git restore --staged --worktree --source=HEAD. On a half-staged file that threw away the staged half as well. git.discardPath now takes unstagedOnly, which runs git restore --worktree and puts the file back to the index. src/tui/local/work.ts passes it for rows in the Changed section. Rows in the Staged section still discard both halves, as before, and untracked rows still delete the file.
What the new test covers. It drives createLocalApp over a real temporary repository and checks each item on the issue:
don a changed file opens a confirm that namesa.txt. Escape leaves the file byte for byte (CRLF, non-ASCII, no trailing newline). Enter alone also discards nothing, because the dialog defaults to Cancel.- Confirming restores the committed content, and the row leaves the Changed section.
- On a half-staged
b.txt, discard drops the unstaged edit. The staged content stays staged. - On a clean tree with no row under the cursor,
dopens no dialog and changes nothing.
I added one unit test to test/git-local.test.ts for unstagedOnly.
Checks. bun x tsc --noEmit is clean, and the new test, git-local and tui-local all pass (45 tests). I didn't run the rest of the suite. I didn't confirm that the half-staged test fails against the old behaviour; the old command would have produced b committed, so it should.
Left out. I didn't change what discarding does from the Staged section.
To try it, run bun test test/tui-local-discard.test.ts.
Approved. The fix is correct and minimal. On a Changed row, d now runs git restore --worktree -- <path>. Arguments are passed as an array with -- before the path, so no shell is built from user text. The staged half of a half-staged file now survives. Staged and untracked rows behave as before.
I checked the pull's head (2779622a) locally:
bun test test/tui-local-discard.test.ts test/git-local.test.ts: 31 pass. The new file passes 5 of 5 on three back-to-back runs.- With the
work.tschange reverted, "on a half-staged path, discard drops only the unstaged half" fails. So the test pins the bug. - The preview answers
/with 200. This change only touches the local terminal, which has no web counterpart to compare.
Two non-blocking nits, for a later pull:
- The
hasCommitrewrap and the graph-assertion rewrap intest/git-local.test.tsare formatting churn unrelated to the issue. Keep them out of single-purpose pulls. sh,settleandtypelikely repeat helpers already intest/tui-local.test.ts. The file header ("The local screens…") is copied from there as well. A shared helper would keep the two in step.
Still open, as the pull says: discarding from the Staged section still drops both halves. That is pre-existing and out of scope here.
din the local terminal is now pinned bytest/tui-local-discard.test.ts. The test also found a real bug, which I fixed in the same pull.The bug. Discarding a row in the Changed section ran
git restore --staged --worktree --source=HEAD. On a half-staged file that threw away the staged half as well.git.discardPathnow takesunstagedOnly, which runsgit restore --worktreeand puts the file back to the index.src/tui/local/work.tspasses it for rows in the Changed section. Rows in the Staged section still discard both halves, as before, and untracked rows still delete the file.What the new test covers. It drives
createLocalAppover a real temporary repository and checks each item on the issue:don a changed file opens a confirm that namesa.txt. Escape leaves the file byte for byte (CRLF, non-ASCII, no trailing newline). Enter alone also discards nothing, because the dialog defaults to Cancel.b.txt, discard drops the unstaged edit. The staged content stays staged.dopens no dialog and changes nothing.I added one unit test to
test/git-local.test.tsforunstagedOnly.Checks.
bun x tsc --noEmitis clean, and the new test,git-localandtui-localall pass (45 tests). I didn't run the rest of the suite. I didn't confirm that the half-staged test fails against the old behaviour; the old command would have producedb committed, so it should.Left out. I didn't change what discarding does from the Staged section.
To try it, run
bun test test/tui-local-discard.test.ts.Closes #7066