Undoing a mistake in Git
Git can undo almost any mistake, because it keeps every commit. Which undo is safe depends on how far the mistake has gone: only in your files, staged, committed, or already shared.
A price is typed as 21.0 instead of 2.10. Caught early, it takes one command to fix. Caught after a colleague pulled it, it needs a different one.
By the end of this lesson
Note
I can undo a mistake without losing work.
Key words
| Word | What it means |
|---|---|
| Restore | to bring a file back to how a commit had it |
| Revert | to make a new commit that cancels an earlier one |
| Reset | to move a branch back to an earlier commit |
| Reflog | Git's private list of where HEAD has been |
| Shared | a commit that others may already have pulled |
The cells students fill in are left blank in this preview.
Restore undoes changes that are not committed
If you edited a file and want it back as the last commit had it, use git restore and the file name. If you staged it, git restore --staged takes it out of the staging area and keeps your edit.
The table lists the four situations and the safe undo for each.
Worked example: pick the undo by the mistake
| Where the mistake is | Safe undo | What it does |
|---|---|---|
| Edited, not staged | git restore FILE | Brings the file back to the last commit |
| Staged, not committed | git restore --staged FILE | Unstages it and keeps your edit |
| Committed, not shared | git reset --soft HEAD~1 | Undoes the commit and keeps its changes staged |
| Committed and shared | git revert COMMIT | Adds a new commit that cancels the old one |
The cells students fill in are left blank in this preview.
Make a repository called undo
git init -b main undoShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make a file with two prices
printf 'Latte 3.20\nTea 2.10\n' > undo/prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Stage the file
git -C undo add prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Save the first commit
git -C undo commit -m "Add prices"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Type a wrong price by mistake
printf 'Tea 21.0\n' >> undo/prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
See where the file stands
git -C undo status --shortShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Bring the file back
git -C undo restore prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read the file
cat undo/prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Revert undoes a shared commit safely
Once others have your commit, never rewrite it. Use git revert. It makes a new commit that does the opposite of the old one. The old commit stays in the history.
Everyone who pulls gets the new commit, so nobody's history is rewritten under them. The option --no-edit keeps Git's own message.
Add a wrong line
printf 'Cake 3.50 oops\n' >> undo/prices.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Commit it by mistake
git -C undo commit -am "Add cake by mistake"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Cancel the last commit
git -C undo revert --no-edit HEADShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Read the log
git -C undo --no-pager log --format=%sShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Reset moves back and the reflog remembers
git reset --soft HEAD~1 moves the branch back one commit and keeps the changes staged. It is safe for a commit nobody has. The option --hard also throws the changes away, so do not use it on work you want.
Git also keeps a private list of where HEAD has been, the reflog. If a commit seems lost, the reflog still names it. The next command reads it.
Read where HEAD has been
git -C undo reflog --format=%gsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think git reset --hard is just another undo. It is not. It throws away every uncommitted change, and Git usually cannot bring those back. Use restore for files, revert for shared commits, and reset only on commits nobody has.