Everyone makes mistakes: editing the wrong file, committing too early, writing a typo in a commit message or committing a change that breaks the site. One of Git's best features is that almost every mistake can be undone.
The right command depends on where the mistake is. Has the change only been made in your files? Has it been staged? Has it been committed? And has that commit already been shared with other people? Each situation has its own safe fix.
In this lesson you'll learn the five undo tools beginners need: git restore, git commit --amend, git revert, git reset and git stash.
Undoing changes that aren't committed
- Discard edits to a file and go back to the last committed version:
git restore index.html- Unstage a file you added by mistake, keeping your edits:
git restore --staged index.htmlgit status even suggests these commands next to each file. Be careful with the first one: edits you discard were never committed, so Git can't bring them back.
Fixing the last commit with --amend
Forgot a file, or made a typo in the message? If you haven't pushed the commit yet, amend it:
git add forgotten-file.css
git commit --amend -m "Add contact page and its styles"--amend replaces the last commit with a new one that includes the staged changes and the new message. Because it replaces a commit, don't amend commits that other people already have.
git reset and git stash
git reset moves the current branch back to an earlier commit:
git reset --soft HEAD~1removes the last commit but keeps its changes staged.git reset HEAD~1removes the last commit and keeps the changes as unstaged edits.git reset --hard HEAD~1removes the last commit and throws its changes away.
HEAD~1 means "one commit before HEAD". Only reset commits that haven't been pushed.
git stash is different: it puts your uncommitted changes on a shelf so you can switch tasks, then git stash pop brings them back.
Undoing Changes in Git Syntax
Undo commands
git restore <file> # discard edits
git restore --staged <file> # unstage
git commit --amend -m "msg" # fix last commit
git revert <hash> # undo a commit with a new commit
git reset --soft HEAD~1 # remove last commit, keep changes staged
git stash # shelve changes
git stash pop # bring them backUndoing Changes in Git Summary
git restore <file>discards uncommitted edits;git restore --staged <file>unstages.git commit --amendfixes the last commit before it's pushed.git revert <hash>adds a new commit that undoes an old one, safe for shared history.git resetmoves a branch back;--hardalso discards changes. Only use it on unpushed commits.git stashandgit stash poppark and restore unfinished work.
Undoing Changes in Git Examples
Each example shows the code, the output it produces and what each part does.
Discard and unstage
git status --short
git restore --staged notes.txt
git restore index.html
git status --shortA notes.txt
M index.html
?? notes.txtLine-by-line explanation
- Line 1notes.txt is staged (A) and index.html has unstaged edits (M).
- Line 2Unstage notes.txt. It becomes untracked (??) again, but the file is kept.
- Line 3Throw away the edits to index.html. It no longer appears in the status.
Fix the last commit message
git commit -m "Add contcat form"
git commit --amend -m "Add contact form"
git log --oneline -1[main 8a2f6c0] Add contcat form
1 file changed, 24 insertions(+)
[main 1e93b47] Add contact form
Date: Mon Sep 2 10:14:03 2024 +0100
1 file changed, 24 insertions(+)
1e93b47 (HEAD -> main) Add contact formLine-by-line explanation
- Line 1A typo in the message.
- Line 2--amend replaces the commit. Notice the new hash.
- Line 3Only the corrected commit is in the history.
Revert a pushed commit
git log --oneline -3
git revert 0c3b9d4 --no-edit
git log --oneline -3e7d0b3c (HEAD -> main) Merge branch 'footer-links'
0c3b9d4 Change button colour to red
52ac9e1 Add dark colour scheme
[main 6f1d8e9] Revert "Change button colour to red"
1 file changed, 1 insertion(+), 1 deletion(-)
6f1d8e9 (HEAD -> main) Revert "Change button colour to red"
e7d0b3c Merge branch 'footer-links'
0c3b9d4 Change button colour to redLine-by-line explanation
- Line 2revert creates a new commit that undoes 0c3b9d4. --no-edit accepts the default message.
- Line 3The original commit is still in the history, followed by the revert.
Stash work to switch tasks
git stash
git switch main
# fix the urgent bug and commit it here
git switch dark-mode
git stash popSaved working directory and index state WIP on dark-mode: 52ac9e1 Add dark colour scheme
Switched to branch 'main'
Switched to branch 'dark-mode'
On branch dark-mode
Changes not staged for commit:
modified: styles.css
Dropped refs/stash@{0}Line-by-line explanation
- Line 1Unfinished changes are shelved, leaving a clean working tree.
- Lines 2 to 4You can now switch branches and work on something else.
- Line 5stash pop puts the changes back and removes them from the shelf.
Common Undoing Changes in Git Mistakes
Using reset --hard on shared commits
git reset --hard HEAD~2
git push --forcegit revert <hash-of-bad-commit>
git pushRewriting pushed history breaks your teammates' copies. Revert adds a fix without rewriting anything.
Discarding work you meant to keep
git restore styles.css # all uncommitted edits are gonegit stash # keep them safely on the shelfIf you're not sure you want to throw changes away, stash them instead.
Amending after pushing
git push
git commit --amend -m "Better message"
git push # rejected: your branch and origin have divergedgit push
git commit -m "Fix typo in heading" # make a new commit instead
git pushUndoing Changes in Git in Real Projects
Undo in practice
When a release breaks the live site, teams usually git revert the bad commit and deploy again within minutes, then fix the problem properly later. Developers use git stash constantly when an urgent bug interrupts a half-finished feature, and --amend to tidy commits before opening a pull request.
Undoing Changes in Git FAQ
How do I undo git commit --amend?
Run git reset --soft HEAD@{1}. HEAD@{1} is where your branch pointed before the amend, so this puts the branch back on the original commit and leaves the amended changes staged. You can then commit them separately or adjust them.
How do I change the message of an older commit?
Use an interactive rebase: git rebase -i HEAD~3, change pick to reword on the commit you want, save, and Git lets you edit that message. This rewrites the commit and everything after it, so only do it on commits you haven't pushed or shared.
How do I restore a file to how it was in an earlier commit?
Run git restore --source=3f9c2ab path/to/file, using the hash of the commit that has the version you want. Only that file changes in your working folder; the history stays as it was. Commit the file afterwards if you want to keep the old version.
How do I undo a git revert?
A revert is just a normal commit, so you can revert it too: git revert <hash-of-the-revert> brings the original changes back. If the revert hasn't been pushed yet, git reset --hard HEAD~1 removes it instead, as long as you have no uncommitted work to lose.
Can I get my work back after git reset --hard?
Committed work, yes: run git reflog, find the commit your branch was on before the reset, and run git reset --hard with that entry, such as HEAD@{1}. Changes that were never committed or stashed can't be recovered this way, because Git never stored them.
Undoing Changes in Git Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the command to unstage logo.png without losing your changes.
git logo.png
A bad commit has already been pushed and your teammates have pulled it. How should you undo it?
What does git reset --soft HEAD~1 do?
After git stash, what does git status show?
A bad commit is already pushed and shared. What's the safest way to undo it?
Undoing Changes in Git Quiz
5 questions to check what you learned.
Which command discards uncommitted edits to a file?
- git revert file
- git restore file
- git remove file
- git stash pop file
What does
HEAD~1refer to?- The first commit ever
- The commit before the current one
- The next commit
- The main branch
Why is
git revertsafe for shared history?- It adds a new commit instead of changing existing ones
- It deletes the bad commit everywhere
- It asks teammates for permission
- It only works offline
Which command brings back changes saved with git stash?
- git stash undo
- git restore --stash
- git unstash
- git stash pop
What does
git restore --staged filedo?- Deletes the file
- Restores the file from GitHub
- Unstages the file but keeps your edits
- Commits the file