You edited a file, and now you don't want the edits. You want the
file back the way it was in the last commit. This is the everyday
"undo my changes" operation, and Git has a specific command for
it: git restore.
The command
git restore README.md
Git takes the last committed version of README.md and writes it
over the current file on disk. Your unstaged edits are gone. The
staging area is untouched.
You'll see git checkout -- README.md used for the same purpose
in older material. It works, but it's the same command as
"checkout a branch" wearing a different hat, and it's easy to
misuse. git restore was introduced to be the clear, focused way
to do this specific thing. Use restore when you have the
choice.
What "restore from where" actually means
By default git restore takes the version from the staging
area. If you haven't touched staging, that's the same as the
last commit, and the effect is what you'd expect: the file goes
back to its committed state.
If you want to be explicit about where to restore from:
git restore --source=HEAD README.md
That says "get the file from the last commit, not the staging
area." Useful when you have some staged changes you want to keep
but a further unstaged edit you want to discard, though the
default without --source usually does what you want.
There is no undo for this
git restore is destructive. Once it overwrites the file, the
edits are gone. Not from disk, not from Git, not from the
reflog. Uncommitted changes are the one thing Git cannot rescue
you from.
If you're on the fence about whether to keep some changes:
- Commit them first, even as a WIP commit. You can always
git resetor amend later. - Or stash them:
git stash push -m "maybe useful". Same effect: your work is saved somewhere Git can find it.
Only run git restore when you're sure. The command is fast; the
unstuck feeling is instant; the regret is longer.
Restoring multiple files at once
git restore accepts multiple paths and glob patterns:
git restore README.md CHANGELOG.md
git restore "src/*.js"
git restore .
The last one, git restore ., restores every modified file in the
current directory. Extremely convenient. Extremely dangerous. Only
use it when you're certain you want to throw away every unstaged
change in the tree.
What restore does NOT do
git restore won't touch:
- Staged changes. For those,
git restore --staged <file>(see the unstaging lesson from the basics module). Different operation. - Untracked files. A brand new file Git isn't watching yet is
invisible to restore. To delete those,
git clean -f(with a dry run first:git clean -n). - Committed changes. Restore only affects your working tree. The commits themselves are unchanged.
Each of these has its own command for a reason. Read the file
list from git status before running any of them, and you'll
know exactly what will change.