Undoing Mistakes
Git's greatest superpower is the ability to undo. There are three main tools — each suited to different situations.
1. git restore — Discard Working Changes
You edited a file but want to throw away those changes and go back to the last commit:
git restore README.md
To unstage a file (undo git add) without throwing away the edits:
git restore --staged README.md
git restore discards uncommitted changes permanently. There's no undo for the undo. Only use it when you're sure you don't want those changes.
2. git reset — Move HEAD Backwards
git reset moves the branch pointer backwards, effectively "uncommitting" commits.
--soft (keep changes staged)
git reset --soft HEAD~1
Moves back one commit. Your changes are still staged, so you can immediately re-commit with a better message.
--mixed (keep changes unstaged) — default
git reset HEAD~1
Moves back one commit. Changes go back to "modified but unstaged."
--hard (discard everything)
git reset --hard HEAD~1
Moves back one commit and throws away the changes. Use with care.
git revert instead.
3. git revert — Safe Undo for Shared History
git revert creates a new commit that undoes the changes from a previous commit. It doesn't rewrite history — it adds to it.
git revert HEAD # undo the last commit git revert a1b2c3d # undo a specific commit
This is always safe to use, even on shared branches, because the history is preserved.
Which Should I Use?
- restore — discard uncommitted edits in working tree
- reset --soft/--mixed — undo local commits, keep the work
- reset --hard — nuclear option, throw everything away
- revert — undo a commit safely on a shared branch
Your Challenges
git log --oneline to see the pre-loaded history
git reset HEAD~1
git add . && git commit -m "Better message"
git revert HEAD