Introduction
Git provides several ways to undo, depending on whether the change is in your working tree, in the index, in your latest commit, or already pushed. Choosing the right tool prevents accidents.
Discarding working-tree edits
You edited a file but want to throw the changes away:
git restore file.txt # modern
git checkout -- file.txt # classic equivalent
git restore with no --source uses the index, so the file returns to its last git add state.
Unstaging
You ran git add but want to take a file out of the next commit (without losing edits):
git restore --staged file.txt
git reset HEAD file.txt # older syntax
Amending the last commit
You committed but want to fix the message or include another file:
git commit --amend -m "Better message"
git add forgotten.txt
git commit --amend --no-edit
Only amend commits you have not pushed, or be ready to force-push.
Reverting a public commit
If a bad commit is already pushed, do not rewrite history. Create a new commit that undoes it:
git revert <sha>
git push
git revert opens an editor with a generated message; the result is a clean undo that everyone can pull.
Resetting
git reset moves the current branch pointer. It has three modes:
--soft: move branch only; keep index and working tree.--mixed(default): move branch and reset index; keep working tree.--hard: move branch, reset index, reset working tree. Destructive.
git reset --soft HEAD~1 # uncommit, keep changes staged
git reset HEAD~1 # uncommit, keep changes unstaged
git reset --hard HEAD~1 # nuke last commit and changes
Recovering from --hard
git reflog
git reset --hard HEAD@{1}
The reflog remembers every move of HEAD for 90 days.
Choosing the right undo
A simple decision matrix:
- Working-tree only:
git restore <file> - Staged file:
git restore --staged <file> - Last unpushed commit:
git commit --amendorgit reset --soft HEAD~1 - Pushed commit:
git revert <sha> - Whole branch tip:
git reset --hard ORIG_HEAD(after a bad merge/rebase)
git status
git diff
git log --oneline -5
Always run those three before any destructive undo. They show the working tree, staged changes, and recent history; together they tell you which undo is safe.
Common mistakes
Confusing revert with reset. Revert adds; reset removes. Running git reset --hard with uncommitted work, then realizing you needed it; reach for the reflog immediately, before garbage collection runs. Amending a pushed commit and not coordinating the force-push with teammates. Use git revert on shared history. And finally, treating git checkout file as safe; in older Git it silently overwrites your edits with no recycle bin. Modern git restore is no different; back up first if unsure.