git reset HEAD~1. It removes the commit and returns its changes to your working tree (unstaged). Use git reset --soft HEAD~1 to keep them staged.Guide
Committed too soon, wrote the wrong message, or pushed a mistake? Every commit-level undo, decoded.
Once something is committed it's very hard to truly lose, even if you "delete" it — Git keeps a log of where you've been (Recover Lost Work shows how to read it). This chapter covers undoing commits: fixing the last one, un-committing, and reversing one that's already pushed. For edits you haven't committed yet, the gentler tools live in Discard & Unstage Changes.
The one rule that keeps you safe: amend and reset rewrite local history — perfect before you push. Once a commit is pushed and shared, undo it with revert instead (it adds a new commit rather than rewriting the old one).
--amend
Typo in the message? Forgot to include a file? git commit --amend replaces the
most recent commit with a new one. To fix just the message, run it alone. To add a forgotten
file, stage it first, then amend.
Repair the most recent commit
$ git commit --amend -m "Better message" # fix the message
$
$ # or: include a file you forgot
$ git add forgotten-file.css
$ git commit --amend --no-edit # keep the same message Only amend commits you haven't pushed yet — amending rewrites the commit, which confuses anyone who already pulled it.
reset
Committed too soon? git reset HEAD~1 removes the last commit and drops its
changes back into your working tree so you can redo them. HEAD~1 means "one
commit before now".
Un-commit, keep the changes
$ git reset HEAD~1 # changes return, unstaged (default = --mixed)
$ git reset --soft HEAD~1 # changes return, still staged The three reset modes, in plain English (all move the branch back, they differ in what they keep):
--soft → keeps your changes staged · --mixed (default)
→ keeps changes unstaged · --hard → deletes the
changes too. Reach for --soft or --mixed day to day; treat
--hard with care.
git reset --hard moves the branch back and discards the changes. It's the
fastest way to wipe local experiments — and the easiest way to lose work, so double-check first.
Discard the last commit AND its changes
$ git reset --hard HEAD~1
$ # everything from that commit is gone from the working tree Pushed that commit already? Don't reset --hard it — use git revert below instead.
revert
For shared history, you don't erase — you add a new commit that reverses an old one.
git revert does exactly that, keeping everyone's history consistent.
Reverse a commit with a new commit
$ git revert a1b2c3d # creates a commit that undoes a1b2c3d
$ git push Use this for anything already on GitHub. It's the team-safe undo.
Quick map: fix last commit → --amend · un-commit keep work → reset · undo a pushed commit → revert · discard uncommitted edits → Discard & Unstage · work seems gone → Recover Lost Work.
Up next: the classic panic — you committed, then noticed the status bar says the wrong branch. Nothing is lost.
FAQ
git reset HEAD~1. It removes the commit and returns its changes to your working tree (unstaged). Use git reset --soft HEAD~1 to keep them staged.git commit --amend -m "Better message" replaces the most recent commit's message. In VS Code: Source Control '…' menu → Commit → Commit Staged (Amend). Only amend commits you haven't pushed.reset rewrites local history — use it before pushing. revert adds a new commit that undoes an old one, which is safe for commits you've already shared.git reflog can find the "lost" commit's hash. Recover Lost Work walks through the whole rescue.