How to undo a Git commit — 3 commands for 3 situations

"Made a commit, and there's a typo / the wrong files / it was pointless" — and the panic hits, like the work is gone. Relax: Git has a rare superpower — it almost never erases anything for good. Even "deleted" commits sit in a special log for a while. Undoing a commit is a one-command job. All you need is to figure out which of three situations you're in.
Step 1. Figure out what exactly you're undoing
Before typing anything, answer two questions:
- Is the commit already pushed to GitHub, or is it still only local?
- Do you want to keep the changes from the commit (just rebuild the commit) or throw them away entirely?
The command depends on the answers. Mixing them up is the only way to actually lose work, so thirty seconds of diagnosis pays off.
Step 2. Local commit — undo but keep the changes
The most common case: you committed too early and want to redo it. The commit hasn't left for the server yet.
git reset --soft HEAD~1
HEAD~1 means "one commit back." --soft means: dissolve the commit but keep all the changes — they're staged again, ready to commit. Edit and commit anew. If you want the changes back but unstaged, use git reset HEAD~1 without the flag.
Important: do this only while the commit is not pushed. Rewriting history others have already seen is a road to pain.
Step 3. Commit already pushed — undo it with revert
If the commit is already on GitHub, you can't erase it — others have it. The right move is to make a new commit that cancels the old one:
git revert <commit_hash>
Find the hash in git log. revert doesn't rewrite history — it adds an "opposite" commit on top that cleanly rolls the changes back. The history stays honest, nobody breaks, and you can push safely. This is the safe rollback of something already published.
Step 4. You need to throw away both the commit and the changes
The commit is garbage, and you don't want its code at all:
git reset --hard HEAD~1
--hard wipes both the commit and your working-folder changes. This is the one genuinely dangerous command of the three — it erases unsaved work. Use it only when you're certain. Tip: before --hard, make a backup branch with git branch backup — then everything stays there.
What you get
After the right command, git log shows history without the offending commit (or with an honest revert commit on top). Your working code is in the state you chose: changes kept, or clean. Panic cancelled.
FAQ: git reset or git revert — which one?
Simple rule: not pushed → reset, pushed → revert. reset rewrites history and is great while the commit is only yours. revert appends a cancelling commit on top and is safe for shared history. More commands are in the beginner cheat sheet.
FAQ: I ran reset --hard and everything's gone — can I get it back?
Often yes. Run git reflog — it's a log where Git remembers where HEAD has been over the last few days. Find the line with the commit you want and git reset --hard <hash> takes you back there. This is exactly why Git forgives almost any mistake: what's "lost" is usually still sitting in the reflog.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





