Discarding Working-Tree Changes
You made some edits, realized they were wrong, and want the file back to exactly the way it was when you last committed. git restore does this — but unlike most Git operations, it is destructive. The discarded changes are not staged, not in the repository, and not recoverable from Git.
Knowing when to use it, and when to reach for something safer, is important.
git restore: discard working-tree changes
Section titled “git restore: discard working-tree changes”To discard all changes in a file since the last commit (or last stage, if the file has staged changes):
git restore pine-ridge.txtThe file is overwritten with the version from the staging area. If nothing is staged, it reverts to the last committed version.
To discard changes in all modified files at once:
git restore .This is destructive. The changes are gone. Git has no record of them. There is no undo.
When git restore is safe to use
Section titled “When git restore is safe to use”git restore is the right choice when:
- You made experimental changes that did not work and you want to start fresh from the last commit
- You accidentally edited a file you did not mean to touch
- You want to compare a clean version of a file with a working one and you have already noted or copied the content elsewhere
It is not the right choice when:
- You are not certain the changes are worthless — they might be worth saving somewhere
- The changes are in the staging area (use
git restore --stagedinstead, which does not touch the working tree)
The old syntax: git checkout — file
Section titled “The old syntax: git checkout — file”Before git restore (Git 2.23, 2019), the command was:
git checkout -- pine-ridge.txtThe -- separator distinguishes a filename from a branch name. This form still works and appears frequently in older documentation.
Seeing what you are about to discard
Section titled “Seeing what you are about to discard”Before running git restore, run git diff to review what will be lost:
git diff pine-ridge.txtIf the diff shows work you want to keep, do not discard — stage or commit it first, or copy the changes somewhere else.
Discarding only part of a file
Section titled “Discarding only part of a file”git restore -p <file> enters an interactive mode similar to git add -p, letting you choose which hunks to restore (discard) and which to keep. Useful when a file has both changes you want to keep and changes you want to throw away.
The relationship to the staging area
Section titled “The relationship to the staging area”git restore <file> restores the working tree from the staging area (or the last commit if nothing is staged).
git restore --staged <file> removes the file from the staging area without touching the working tree.
These are two separate operations. Running one does not affect the other.
| Command | What it does |
|---|---|
git restore <file> | Discard working-tree changes (restore from staging area / last commit) |
git restore --staged <file> | Remove from staging area (keep working-tree changes) |
git restore --staged --worktree <file> | Both: unstage and discard working-tree changes |
Exercise
Section titled “Exercise”-
In your
git-practicefolder, make a change topine-ridge.txt— add a line you consider throwaway. Do not stage it. -
Run
git diff pine-ridge.txtto see the change. -
Run
git restore pine-ridge.txt. -
Open
pine-ridge.txtand confirm the change is gone. Rungit status— the file should be unmodified. -
Make another change to
pine-ridge.txt. This time, also add a new unrelated filetemp.txt. Stage onlytemp.txt. -
Run
git restore pine-ridge.txt. Confirm only the working-tree changes topine-ridge.txtare discarded —temp.txtremains staged.
git restore <file>discards working-tree changes, restoring the file from the staging area (or last commit). Destructive — not recoverable.git restore .discards all unstaged changes in the current directory.- Run
git diff <file>before restoring to see exactly what will be lost. git restore -p <file>lets you selectively discard individual hunks.git restore <file>only affects the working tree. It does not touch the staging area.- The old form is
git checkout -- <file>— same effect, still valid.
Next: unstaging files — how to remove a file from the staging area without losing the changes in your working tree.