Undoing Mistakes
Git keeps history so you can go back. Which command to use depends on whether the change is uncommitted, committed locally, or already pushed.
Which command for which situation
| Situation | Command |
|---|---|
| Throw away uncommitted changes in a file | git restore <file> (the changes are lost) |
| Unstage a file but keep the changes | git restore --staged <file> |
| Change the last commit’s message, or add a forgotten file (not pushed) | git commit --amend |
| Undo the last commit but keep the changes | git reset --soft HEAD~1 (changes stay staged) or git reset HEAD~1 (unstaged) |
| Throw away local commits and changes | git reset --hard <commit> (uncommitted changes are lost; the removed commits stay in the reflog) |
| Undo a commit that has been pushed | git revert <commit> (adds a new commit that reverses it) |
| Stop a merge that went wrong | git merge --abort |
| Set work aside for a moment | git stash, later git stash pop |
| Find a commit you seem to have lost | git reflog, then git switch -c rescue <hash> |
Rules of thumb
- Shared history is not rewritten. If others may have pulled the commit, use
git revert. Do not usereset,amendor rebase followed by a force push. - Look before you leap. Run
git statusandgit log --onelinefirst. Commands marked as losing changes cannot be undone, because uncommitted work was never recorded. - Committed work is hard to lose.
git refloglists where your branches have been, and unreferenced commits are kept for at least 30 days by default. - If you really must force-push your own branch, use
git push --force-with-lease, which refuses to overwrite commits you have not seen.
Try it
In a test repository, make a commit and undo it three ways: with reset --soft, with revert, and, after a reset --hard, by recovering it with reflog.
Common mistakes
- Running git reset --hard without checking git status first.
- Amending or force-pushing a commit that others have already pulled.
Check yourself
- You committed to the wrong branch and have not pushed. How do you move the commit?
- Why is git revert safe on shared history when git reset is not?