Skip to content

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

Closed
1 of 1 issue completed

Description

@jamescrosswell

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

  1. 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.
  2. 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 until Ctrl+S, and closing the tab leaves the file deleted. And it still touches the index.
  3. 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's M. The restored file then leaves the review on save. A new file shows as soon as it exists, as it would in git status. The index stays the user's. Costs a second git call per refresh, and scratch files that aren't ignored now show.
  4. 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

Delivery

One PR.

Decided

All by the Lead, accepted when you approved:

  • Untracked counts, ignored doesn't. That's what git status and git add -A go 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 add shows as D and A, as git status shows it. Once added, -M pairs 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

  1. On a branch, git rm a file that main has, and commit.
  2. Open the Review tab (Ctrl+Shift+R), Enter on the deleted file, and press Ctrl+R (rc). The status bar says <name> restored — Ctrl+S to write it back.
  3. 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

  1. added
    rank:highThe a-team Lead recommends High; your Priority still decides
    on Oct 23, 2026
  2. a-team-app commented on Oct 23, 2026

    @a-team-app
    Contributor

    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

  3. added
    pitchAn a-team pitch: Lead shapes it, reviewer approves it
    on Oct 23, 2026
  4. changed the title [-]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[/+] on Oct 23, 2026
  5. a-team-app commented on Oct 23, 2026

    @a-team-app
    Contributor

    Pitched for you. One thing to flag: my rank recommendation said a one-line git add on 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.

  6. a-team-app commented on Oct 23, 2026

    @a-team-app
    Contributor

    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.

  7. a-team-app commented on Oct 23, 2026

    @a-team-app
    Contributor

    Tried on origin/main (c534098) in a scratch repo where the branch had committed deleting old.md, with old.md put back on disk unstaged and a new New.cs not added. The Review tab listed App.cs and New.cs (+3, added), 2 files, and no old.md. git status afterwards still showed both as untracked, so the index was left alone. Closing as done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpitchAn a-team pitch: Lead shapes it, reviewer approves itrank:highThe a-team Lead recommends High; your Priority still decidestheme: Seeing changeThe vision theme the a-team Lead says this pitch serves

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions