All chapters in this track
- 011. The Mental Model
- 022. Essential Setup
- 033. Core Daily Workflow
- 044. Branching
- 055. Merging & Conflict Resolution
- 066. Rebasing
- 077. Remote Repositories
- 088. Stashing
- 099. Undoing Things
- 1010. Tagging & Versioning
- 1111. Cherry-Pick
- 1212. Git Bisect & Blame
- 1313. Git Hooks
- 1414. Submodules
- 1515. Team Workflows
- 1616. Power Commands & Aliases
- 1717. Reflog: The Safety Net
- 1818. Practice Tasks
- 19Quick Reference Cheatsheet
Chapter 9 of 19
9. Undoing Things
This is where most developers get stuck. Know the right tool for each situation.
Before committing
# Unstage a file (keep working dir changes)
git restore --staged file.txt
# Discard working dir changes (PERMANENT — can't recover)
git restore file.txt
git restore . # discard ALL working dir changes
# Undo all working dir changes back to last commit
git checkout -- . # older syntax (same effect)
After committing
# Amend the last commit (local only — don't amend pushed commits)
git commit --amend -m "corrected message"
# Undo last commit, keep changes staged
git reset --soft HEAD~1
# Undo last commit, keep changes unstaged
git reset HEAD~1 # (default: --mixed)
# Undo last N commits, keep working dir intact
git reset HEAD~3
# Nuclear: undo last commit, discard all changes (DESTRUCTIVE)
git reset --hard HEAD~1
# Safe undo for pushed commits: create a reverting commit
git revert HEAD # reverts last commit, makes new commit
git revert a1b2c3 # revert specific commit
git revert HEAD~3..HEAD # revert a range
Reset modes at a glance
| Mode | Staging | Working Dir | Use when |
|---|---|---|---|
--soft | keeps staged | untouched | Re-commit with changes |
--mixed | unstages | untouched | Rework what to include |
--hard | cleared | cleared | Truly discard everything |
Restore a deleted file
git checkout HEAD -- deleted-file.txt # restore from last commit
git show HEAD:path/to/file > recovered.txt # extract to a new file