git restore
Beginner Git CLI Careful
Summary: git restore <file> overwrites the working-tree file with the staged version (or, if none, the last commit's), discarding your edits. git restore --staged <file> takes the file out of the staging area without touching your edits. --source=<commit> picks any historical version.
Careful — the plain form deletes uncommitted changes with no way back. --staged is harmless.
What it does
Copies content into the working tree or the staging area from a source: by default the staging area (for the working tree) or HEAD (for the staging area). It never creates commits and never moves branches — that distinction from reset is the point of its existence.
Why it exists
Before Git 2.23, git checkout -- <file> and git reset HEAD <file> did these jobs, and beginners mixed them up with branch switching and history rewinding. restore does only file-level undo, and says so in its name.
When to use it
- You edited a file and want the committed version back.
- You staged a file that should not be in the next commit.
- You want yesterday's version of one file to look at or to commit again:
--source.
When not to use it
- To undo a commit:
git revert(safe) orgit reset(careful). - On a file whose uncommitted edits you might still want:
git stashinstead. - To switch branches:
git switch.
Syntax
| Form | Effect |
|---|---|
git restore <file> |
Discard unstaged edits (working tree ← staging area) |
git restore --staged <file> |
Unstage (staging area ← HEAD); working tree untouched |
git restore --staged --worktree <file> |
Both: unstage and discard |
git restore --source=<commit> <file> |
Working tree ← that commit's version of the file |
git restore . |
Discard all unstaged edits in the current folder and below |
Examples
Discard an edit:
$ git status -s M README.md$ git restore README.md
$ git status -s
(Silence: clean.)
Unstage, keeping the edit:
$ git status -sM docs/faq.md$ git restore --staged docs/faq.md
$ git status -s M docs/faq.md
An older version into the working tree:
$ git restore --source=HEAD~3 README.md
$ git status -s M README.mdNow git diff shows how the old version differs; commit it to make the rollback part of history, or git restore README.md to go back to the current version.
Expected result
The named file changes on disk (plain form, --source) or in the staging area (--staged); git status reflects it immediately. No commit, no branch movement.
Common mistakes
- Plain
restoremeant as unstage. The edit is gone. Read the hint ingit status: it always names the right form. git restore .in the wrong folder or with a forgotten important edit. Rungit difffirst and read what you are about to lose.- Restoring a file that has both staged and unstaged edits. Plain restore drops only the unstaged part (back to the staged version). Use
--staged --worktreeto drop both. - Expecting restore to recover a deleted commit. It works with files; commits are
git reflog's job.
How to undo or recover
- After
--staged:git add <file>stages it again; nothing was lost. - After a plain
restore: the uncommitted edit is unrecoverable by Git. IntelliJ's Local History or an editor's undo buffer may still have it. This is the reason to commit or stash before experiments. - After
--source:git restore <file>(from the staging area) orgit restore --source=HEAD <file>brings the current version back.
In VS Code
Discard Changes (the ↶ icon on a file) is the plain form; the − on a staged file is --staged. Both ask for confirmation.
In IntelliJ IDEA
Rollback on a file is the plain form (IntelliJ's Local History keeps a copy); with the staging area enabled, − is --staged.
Related commands
git status prints the right restore form as a hint · git stash parks edits instead of destroying them · git reset is the branch-level cousin · git checkout is the older command that did both jobs.
Lessons that use this command
Undo, beginner edition · File states · Staging with git add.