Git restore returned the staged version: choose the source and destination
By ON Lab · Sources checked November 8, 2026
With no explicit source or staged option, git restore copies from the index into the working tree. If you staged one version and then edited further, the default restore returns the working file to the staged version, not necessarily the last commit. Restoring the index with staged uses HEAD by default. Choose both source and destination before running a command that discards edits.
The reader task: keep the staged checkpoint
A public editor discussion asks for a way to discard later experiments while keeping a staged version. That is a useful reader problem, but some command descriptions in the question do not match the current Git reference. In particular, HEAD names the committed source, so explicitly selecting it does not mean selecting the index.
We used the official Git restore documentation and a local three-version experiment to resolve that ambiguity. The editor's current Restore File implementation was not tested. A graphical action may issue a different command, so do not infer its source from its label alone.
Keep three versions distinct
| Location | Example text | Meaning |
|---|---|---|
| HEAD | committed | Contents in the current commit |
| Index | staged | Contents currently prepared for a commit |
| Working tree | unstaged | Contents currently in the editable file |
All three can differ at once. A file shown in both staged and unstaged groups is not necessarily duplicated or corrupt. It can mean you staged a useful checkpoint, then continued editing the same file.
git status --short
git diff -- draft.txt
git diff --cached -- draft.txt
The ordinary diff compares working tree with index. The cached diff compares index with HEAD. Inspect both and save any version you still need outside the destructive operation. Git cannot reliably recover every uncommitted edit that you overwrite.
Our first restore: working tree from index
In a disposable repository we committed draft.txt containing committed, replaced it with staged and added it to the index, then replaced the working file with unstaged. After this command:
git restore -- draft.txt
The working file contained staged. The index still contained staged and HEAD still contained committed. The later unstaged experiment was discarded from the working file. This is the default behavior documented for a restore without staged or an explicit source.
Run such a command only after deciding that the current working edits can be discarded. The double dash separates the path from options; replace the example with the exact reviewed path. Using a dot or wildcard broadens the set of files affected.
Our second restore: index from HEAD
Starting with the working file and index both containing staged, we ran:
git restore --staged -- draft.txt
The index returned to committed while the working file remained staged. Git now showed a working-tree modification relative to the restored index. Unstaging did not erase the file's contents or automatically return the editable file to HEAD.
That is why an unstage action can appear to move a change into another group in an editor. It changes what is prepared for the next commit, not necessarily the file you are reading. Inspect the file and both diffs afterward.
When an explicit source changes the result
The source option names the tree to restore from. Selecting HEAD targets committed contents; selecting a different commit targets that commit's contents. Destination flags decide whether the index, working tree, or both are changed. The official reference also notes that a tracked path absent from the selected source is removed to match that source.
Do not copy a command described as “restore to staged” if it explicitly names HEAD and your intended checkpoint is different from HEAD. Read the command itself. Similarly, do not combine staged and worktree simply because you want a cleaner status display: that changes two destinations.
This guide deliberately does not offer a whole-repository discard shortcut. The reader task is to preserve one selected version of one file. Use the smallest reviewed path and verify the before-and-after contents.
If the editor result differs
Record the exact action and inspect the Git operation it invokes, if the editor exposes it. Compare the file's contents, index contents, and committed contents. A UI may call reset, checkout, or restore with explicit flags, and those details matter more than the word Restore on a button.
Our test used a normal tracked text file without conflicts. A merge-conflicted index has additional stages, and restoring one side introduces different choices. Submodules, sparse checkouts, filters, and generated files also need their own context. Do not use this simple example as proof that every conflicted or filtered file will behave identically.
Verify the result you intended to keep
Open the working file, inspect the cached diff, inspect the ordinary diff, and confirm that the selected checkpoint survived in the intended location. Then run the project's relevant checks. A status panel becoming empty is not the goal if it discarded work you wanted.
If the intention is to preserve work while changing tasks, the stash inventory guide explains another operation and its untracked-file boundary. Staging alone is not a durable independent backup.
Official documentation and reader discussion checked November 8, 2026. The committed/index/working-tree example and both restore operations were executed in a disposable local repository. Editor UI, conflicts, and recovery of discarded content were not reproduced.