Undoing Mistakes

Course 1 · Ch 8
Undoing Mistakes — The Beginner Toolkit
git restore, soft reset, revert vs reset, and amend — fixing the four most common "I didn't mean to do that" moments

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?

📝 "I edited a file and want to throw the changes away"
Changes are still in the working directory, not staged yet. git restore <file>
📋 "I staged a file by mistake, didn't mean to commit it yet"
Already ran git add, want to unstage without losing the edit. git restore --staged <file>
💬 "My last commit message has a typo"
Only the most recent commit, not yet pushed/shared. git commit --amend
📦 "I committed something I didn't mean to, want it undone"
Need to remove an entire commit — see revert vs reset below, the choice depends on whether it's been pushed. git revert / git reset

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.

$ # Discard unstaged edits to one file
$ git restore index.html

$ # Unstage a file (keeps the edit, just removes it from staging)
$ git restore --staged index.html
git restore (without --staged) permanently discards the edit
Unlike unstaging, plain 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.

$ # Just fix the message
$ 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
Never amend a commit you've already pushed and shared
Amending creates a brand-new commit hash to replace the old one. If anyone else has already pulled the original commit, amending and pushing again creates a conflicting history between your repo and theirs — exactly the kind of situation Course 2's "multiple users on the same branch" scenario chapter exists to help you recover from. Amend freely before pushing; be cautious after.

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.

CommandWhat it doesSafe 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
$ # Undo a commit that's already been pushed and shared — safe
$ 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
The simple rule: has it been pushed?
Not pushed yet, only on your machine → 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