Course contents

Discard an unstaged change

Sign in to run this lab and save your progress

Learn

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 reset or 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.

Your task

The repository has one commit. README.md has been edited but the change is bad — you want to throw it away and return README.md to whatever the last commit had. Use git's tools to restore README.md from the latest commit. After this, git status should report a clean working tree.