Undoing Mistakes
Almost every beginner's biggest fear with git is "what if I break something I can't undo." The reassuring truth: git is built to make almost everything reversible, as long as you know which tool fixes which mistake. This chapter covers the four you'll reach for constantly — undoing uncommitted changes, undoing staging, undoing commits two different ways, and fixing your most recent commit message.
Which Mistake Do You Have?
git add, want to unstage without losing the edit.
git restore --staged <file>
git restore — Undoing Uncommitted Changes
git restore (introduced alongside git switch in Chapter 4 — both replaced overlapping uses of the old git checkout) reverts a file in your working directory back to how it looked at the last commit, discarding any edits since.
$ git restore index.html
$ # Unstage a file (keeps the edit, just removes it from staging)
$ git restore --staged index.html
git restore <file> throws the actual content away — there's no staging-area safety net here, because the change was never committed anywhere git could recover it from. If you're not sure you want to lose the edit, git diff (Chapter 3) first to see exactly what you'd be discarding.
git commit --amend — Fixing Your Last Commit
--amend replaces your most recent commit entirely — useful for a typo'd message, or for adding a file you forgot to stage before committing.
$ git commit --amend -m "Fix login validation bug"
$ # Forgot to add a file? Stage it, then amend
$ git add forgotten-file.js
$ git commit --amend --no-edit
Revert vs Reset — Undoing Whole Commits
Both undo a commit's effects, but in fundamentally different ways — choosing the wrong one is the single most consequential mistake in this chapter.
| Command | What it does | Safe after pushing? |
|---|---|---|
| git revert <commit> | Creates a new commit that undoes the changes from the target commit. History is preserved — both the original mistake and the fix are visible. | ✅ Yes — safe even on shared branches |
| git reset --soft <commit> | Moves your branch pointer back, but keeps all the changes staged — as if you'd never committed, but the edits remain. | ⚠️ Only if not yet pushed |
| git reset --hard <commit> | Moves your branch pointer back AND discards all changes since, in the working directory too. Most destructive option in this chapter. | ❌ Never on shared/pushed work |
$ git revert a1b2c3d
[master 9f8e7d6] Revert "Add experimental feature flag"
$ # Undo a LOCAL-ONLY commit, keep the edits to redo properly
$ git reset --soft HEAD~1
$ # Throw away a local-only commit AND its changes entirely
$ git reset --hard HEAD~1
reset is fine, rewrite away. Already pushed, possibly pulled by someone else → use revert instead, which adds a new commit rather than rewriting history anyone else might be relying on. When genuinely unsure, revert is always the safer default.
Recovering from a hard reset mistake
Even git reset --hard isn't always unrecoverable — git keeps a record of where your branch pointers have recently been, called the reflog. This is genuinely advanced-rescue territory and gets full treatment in Course 3, Chapter 3 ("Reflog and disaster recovery") — but it's worth knowing now that git reflog exists as a safety net, even for mistakes that feel catastrophic in the moment.
Chapter 8 Quick Reference
- git restore <file> — discard unstaged edits (permanent, no staging-area safety net)
- git restore --staged <file> — unstage, keeping the actual edit
- git commit --amend — fix the message or contents of your most recent commit (only safe before pushing/sharing)
- git revert <commit> — undoes a commit by adding a new one; safe even after pushing
- git reset --soft — rewinds the branch pointer, keeps changes staged; local-only commits
- git reset --hard — rewinds AND discards changes entirely; most destructive, local-only commits
- Golden rule: not pushed yet → reset is fine; already pushed/shared → use revert
- Safety net: git reflog can often recover even from a hard reset — full coverage in Course 3
- Next chapter (Scenario): moving your project folder or machine — what breaks, and how to do it correctly