git restore: put a file back and take it out of the index

Updated July 31, 2026

git restore undoes things at the file level: with --staged it takes a file out of the index, without the flag it returns the file to the way the last commit has it. Undoing in git comes in levels, and this command covers the two lowest ones.

Level one: the file is already in the index (staging area) and you changed your mind about committing it.

$ git status --short
M  report.txt

$ git restore --staged report.txt
$ git status --short
 M report.txt

The two columns of the short git status read like this: the first is the index, the second is the working directory. M means "the change is picked into the index", M means "the change is only in the file". The command moves the letter from the first column to the second and loses nothing: git add puts it back.

Level two: the edits in the file itself turned out to be junk and the file has to go back to the last commit.

$ git restore report.txt
$ git status
On branch main
nothing to commit, working tree clean

Slow down here. The file is overwritten with the content from the archive, and edits git never saw are gone for good, because it has nothing to restore them from. A look at git diff before running this pays off.

The default source is the index, and when nothing is staged there, the index holds the content of the last commit. To take the version from another commit, use --source:

$ git restore --source=HEAD~1 report.txt   # the version from one commit back
$ git restore .                            # roll back every file in the current directory

A file you deleted by accident comes back the same way: after rm report.txt, run git restore report.txt and the file is on disk again.

Common mistakes

--staged gets mistaken for a full undo. The flag touches the index only, the content on disk stays as it was. To clear both areas at once you need both flags: git restore --staged --worktree report.txt.

The second trap is advice from articles written before 2019, which offer git checkout -- file and git reset HEAD file for the same jobs. Those commands still work, but each of them carries several unrelated roles. Version 2.23 split the roles up: git switch changes branches, git restore restores files, git reset moves the branch pointer.

Where this is in the book

Undoing level by level is covered in chapter 4, along with git diff and .gitignore.

Chapter 4. Inspect, undo, ignore

To practise it by hand, take the interactive lesson Undoing changes.