Topic 1.3
Undoing Things Safely: restore vs revert vs reset
In one line
Git has several different 'undo' commands that operate on completely different things — restore (working directory/staging), revert (public history), and reset (local history) — and picking the wrong one is the single most common way people accidentally lose work.
Think of it like this
Crossing out a mistake with a single line versus tearing the page out of the notebook entirely. git revert is the crossing-out — it adds a NEW commit that undoes a previous one, leaving the full history (including the mistake) visible. git reset is tearing the page out — it can genuinely remove commits from the branch's history entirely.
Key ideas
- 01
git restore <file>(from Topic 1.1) discards UNCOMMITTED changes in the working directory, restoring a file to match the last commit — this only ever affects uncommitted work, never touches history, and is the safest of these commands. - 02
git revert <sha>creates a BRAND NEW commit that exactly undoes the changes from an existing commit, while leaving that original commit fully intact in history — this is the SAFE way to undo something that's already been pushed and shared with others, since it doesn't rewrite or remove anything anyone else might have already based work on. - 03
git resetmoves the current branch pointer to a different commit, with three modes controlling what happens to the changes in between:--soft(keeps changes staged),--mixed(default; keeps changes in the working directory, unstaged), and--hard(DISCARDS the changes entirely — genuinely destructive, no confirmation, no undo through normal means). - 04
The golden rule for choosing between revert and reset: has this commit been PUSHED and shared with anyone else yet? If yes, use
revert(never rewrite shared history — Phase 5 covers exactly why). If the commit is purely local and nobody else has seen it,resetis fine and often simpler. - 05
git reset --hardis one of the few Git commands that can genuinely destroy uncommitted work with zero warning and no confirmation prompt — always rungit statusandgit difffirst to know exactly what you're about to lose, and remember that Phase 5'sreflogis a real (though not guaranteed) safety net if a reset goes wrong.
Code & diagrams
The one question that decides which undo command is correct.
Practice each command on a throwaway repo — read the output carefully each time.
cd ~/scratch/my-first-repo
# Make a commit you'll then "undo" two different ways
echo "a mistake" >> notes.txt
git add notes.txt
git commit -m "Add a mistake"
# --- Option A: safe undo for an ALREADY-SHARED commit ---
git revert HEAD
# Opens an editor for the revert commit's message — save and close
git log --oneline
# Shows BOTH the original commit AND the new revert commit
# --- Option B: undo for a commit that's still purely LOCAL ---
# (only do this on a commit nobody else has, e.g. undo the revert itself)
git reset --soft HEAD~1
git status
# The revert's changes are now staged, ready to modify or discard
# --hard is destructive — ALWAYS check first
git status
git diff
# git reset --hard HEAD~1 # only run this once you've confirmed what you'd loseExplain it without notes
Why is git revert considered safe to use on a commit that's already been pushed and shared, while git reset is not?
What's the difference between git reset --soft and git reset --hard, in terms of what happens to your changes?
Practice
Make a commit, then use git revert to undo it, and confirm with git log that both the original commit AND the new revert commit are visible in history.
Make a second commit, then use git reset --soft HEAD~1 to undo just the commit while keeping its changes staged — confirm with git status that the changes are still there, ready to recommit.
Trade-offs
- ↔
reset --hardis fast and simple for cleaning up purely local, unshared mistakes, but its complete lack of confirmation makes it genuinely dangerous to reach for out of habit — many experienced developers deliberately default to--softor--mixedunless they're certain they want the changes gone, precisely because--hard's convenience is also its biggest risk.
Done when you can
I know when to use git revert (shared/pushed commits) versus git reset (purely local commits).
I can explain the difference between reset --soft, --mixed, and --hard.
I always check git status and git diff before running git reset --hard.