Repository navigation
My branch review isn't what's on disk: a restored file stays listed as deleted, and a new file I haven't added is missing #593
Description
Opportunity
Reviewing my branch, I restore a file the branch deleted (Ctrl+R on its diff, then Ctrl+S). The file is back on disk with main's content, but the Review tab still lists it as deleted (D, −N) and the file count doesn't drop, even after a refresh. It only leaves once I git add it outside TuiCode. If the deletion wasn't committed, the same steps work. Found while recording the review demo, which works around it by leaving the deletion uncommitted.
It's one case of a wider gap. The Review tab lists what git diff <merge base> sees, which skips untracked files (AGENTS.md, Review tab: "untracked files don't"). So it shows my unstaged edits to tracked files, but not a new file I've created and not yet added. A file I've restored is untracked, so git still reports it as deleted. Either way the review I read before pushing isn't what's on my disk. That choice was never made on purpose: #180 tested only "untracked-but-added".
Options considered
- Stage the file when a restore is saved (
git add -- <path>, as the report suggests). Fixes exactly the reported case in a few lines. But TuiCode never touches the index anywhere else, so saving would quietly stage. A new file I haven't added would still be missing from the review. - Write the restore straight to disk and the index (
git restore --source=<base> --staged --worktree), with no unsaved tab. Also small, but it breaks the rule every revert follows (Discard an unsaved hunk without retyping it (rc) #245, Bring back a file your branch deleted, without leaving the diff #247): nothing is written untilCtrl+S, and closing the tab leaves the file deleted. And it still touches the index. - The Review tab counts untracked files that git doesn't ignore. A file on disk that isn't in the index, and isn't ignored, is compared with the merge base like any other. Missing at the base, it's
A. The same as the base, it isn't listed. Different from the base, it'sM. The restored file then leaves the review on save. A new file shows as soon as it exists, as it would ingit status. The index stays the user's. Costs a second git call per refresh, and scratch files that aren't ignored now show. - Do nothing. Restoring a committed deletion stays a trap, and the review misses new files.
I chose 3. It fixes the bug at its cause, and it makes the review match what will go in with the next git add -A, without TuiCode staging anything.
Proposal
The Review tab lists everything the branch changes on disk against the merge base, untracked files included unless git ignores them. Restoring a deleted file and saving it takes it off the list and lowers the count, whether or not the deletion was committed. A new file shows under A with its line count, and Enter opens it against an empty left side, as an added file does today.
Mockup
Before, after restoring and saving docs/old.md (deletion committed), with src/New.cs created but not added:
┌ Explorer Find Usages Review ─────────────┐
│ feature/x ↔ origin/main • 3 files │
│ ▾ docs │
│ D old.md −42 │
│ ▾ src │
│ M App.cs +12 −3 │
│ M Tool.cs +4 −1 │
└─────────────────────────────────────────────┘
After:
┌ Explorer Find Usages Review ─────────────┐
│ feature/x ↔ origin/main • 3 files │
│ ▾ src │
│ M App.cs +12 −3 │
│ A New.cs +20 │
│ M Tool.cs +4 −1 │
└─────────────────────────────────────────────┘
Both are the Review tab's TreeView as it is today; only which rows it holds changes.
Scope
In
- Untracked, not-ignored files in the Review tab's list, its count and its line counts, compared with the merge base (
A,M, or left out when the same). - Both the branch review and the review against the PR's base.
- Next/previous change (
Alt+Down/Alt+Up) stepping into them like any other file. - AGENTS.md's Review tab section updated to say untracked files count.
Out
- Staging, or any other change to the index.
- A setting to hide untracked files.
- Ignored files: what
.gitignoreleaves out stays out. - Changes to how restore itself works (Bring back a file your branch deleted, without leaving the diff #247): it still opens an unsaved tab, and
Ctrl+Swrites it.
Delivery
One PR.
Decided
All by the Lead, accepted when you approved:
- Untracked counts, ignored doesn't. That's what
git statusandgit add -Ago by, so the review shows what the next commit of everything would hold. A scratch file you haven't ignored shows up. That's honest, and ignoring it is the fix. - An untracked file identical to the base isn't listed, the same as a tracked one. That's what makes the restored file leave the review.
- The index is never written, not even as a temporary intent-to-add in the user's index. If the Dev needs an index to diff against, it's a throwaway one.
- No rename detection for untracked files. A file deleted and recreated under a new name without
git addshows asDandA, asgit statusshows it. Once added,-Mpairs them as today.
Original idea
When a branch has committed a file's deletion, restoring it from the Review tab and saving writes the file back, but the Review tab still lists it as deleted (D, −N), and the file count doesn't change.
Steps
- On a branch,
git rma file thatmainhas, and commit. - Open the Review tab (
Ctrl+Shift+R), Enter on the deleted file, and pressCtrl+R(rc). The status bar says<name> restored — Ctrl+S to write it back. - Press
Ctrl+S.
The file is on disk again with main's content, but the Review tab still lists it as deleted, even after re-pressing Ctrl+Shift+R. It only drops out once the file is git added.
If the deletion wasn't committed yet (plain rm, still in the index), the same steps work: the file leaves the list.
Why
GetChangedFilesAsync runs git diff --name-status <merge-base> -- (src/TuiCode.Workbench/Git/GitCli.cs), which only sees paths in the index. A file whose deletion was committed isn't in the index any more, so the restored file is untracked, and git still reports it as deleted against the merge base.
Expected
After a restore and save, the file matches the merge base, so it leaves the review. Either restore could stage the path (git add -- <path>, or git restore --source=<merge-base> --staged --worktree), or the change list could count untracked files that exist at the merge base as present. The first is simpler, and it matches what a restore means here.
Found while recording the TuiCode demo for reviewing a branch, which works around it by leaving the deletion uncommitted.
Activity
a-team-app commentedon Oct 23, 2026
Recommended: High · theme 2 (Seeing change), tiny · a restored file stays listed as deleted, so the review count lies; a one-line stage on restore fixes it
[-]Restoring a file whose deletion is committed still lists it as deleted in the Review tab[/-][+]My branch review isn't what's on disk: a restored file stays listed as deleted, and a new file I haven't added is missing[/+]a-team-app commentedon Oct 23, 2026
Pitched for you. One thing to flag: my rank recommendation said a one-line
git addon restore would fix it. Once I'd dug in, I went with counting untracked (not ignored) files in the Review tab instead. That fixes the restore case without TuiCode ever staging anything, and a new file you haven't added shows up too. Staging is still listed under Options if you'd rather have the smaller fix.a-team-app commentedon Oct 23, 2026
Broken down into one task, as pitched: #597, Ready now with no dependencies (nothing else in flight touches the Review tab's file list).
Nothing was left to settle: the four Assumed points are now under Decided, as mine, accepted when you approved.
a-team-app commentedon Oct 23, 2026
Tried on
origin/main(c534098) in a scratch repo where the branch had committed deletingold.md, withold.mdput back on disk unstaged and a newNew.csnot added. The Review tab listedApp.csandNew.cs(+3, added),2 files, and noold.md.git statusafterwards still showed both as untracked, so the index was left alone. Closing as done.