Back to articles
GitEngineering

How to Undo Your Last Git Commit (Safely)

Undo a Git commit without losing work — the difference between reset --soft, --mixed, and --hard, when to use revert instead, and how to recover a commit you thought was gone.

Yash Thakur
4 min read
How to Undo Your Last Git Commit (Safely)

The short answer: if the commit is only on your machine and you want to keep the changes, run git reset --soft HEAD~1 — it removes the commit but leaves your work staged. If you want the changes gone entirely, git reset --hard HEAD~1 (destructive). If the commit is already pushed and shared, don't rewrite history — use git revert <hash> to add a new commit that undoes it. And if you ever "lose" a commit, git reflog almost always gets it back.

"How do I undo my last commit" is probably the most-Googled Git question there is, and the top answers are a confusing pile of reset, revert, and --hard with no explanation of which is safe when. Here's the decision laid out so you pick the right one the first time instead of making it worse.

First question: is the commit pushed and shared?

This single question decides everything.

  • Not pushed (local only): you can safely rewrite history with reset. No one else has the commit, so changing it affects nobody.
  • Already pushed to a shared branch: do not reset and force-push. Rewriting shared history breaks everyone else's clone and is how teams lose work. Use revert instead.

Get this right and the rest is mechanical.

Local commit: git reset and the three flags

git reset HEAD~1 moves your branch back one commit. The flag decides what happens to the changes from that commit:

The mental model:

  • --soft — "I committed too early / with a bad message." Your files are untouched and staged; just commit again. This is the one you want most often.
  • --mixed — "I committed the wrong set of files." Changes stay in your working tree but unstaged, so you can re-add selectively.
  • --hard — "those changes were a mistake, delete them." Only reach for this when you're sure, because it discards uncommitted work in the process.

Just fixing the message or adding a file?

If you don't want to remove the commit at all — only amend it — don't reset:

Note that --amend also rewrites history, so the same "is it pushed?" rule applies — amend freely on local commits, avoid it on shared ones.

Pushed commit: git revert

When the commit is already on a shared branch, the safe undo is a new commit that reverses it. History stays intact; collaborators just pull one more commit.

revert is the only correct answer on main/shared branches. It's auditable (the undo is in the history), it doesn't require a force-push, and it won't detonate anyone else's working copy. It's the same instinct behind shipping fast without breaking things: the safe path and the fast path are usually the same path once you stop rewriting shared state.

"I ran --hard and lost a commit" — reflog to the rescue

This is the one that saves careers. Git keeps a log of everywhere HEAD has pointed, even across resets, for ~90 days by default. So a commit you "destroyed" with --hard is usually still recoverable:

reflog is the reason reset --hard is scary-but-not-fatal: as long as the commit existed, it's probably still findable. Reach for it the moment something feels gone before you panic.

The one-screen decision

| Situation | Command | |-----------|---------| | Committed too early, want to redo it | git reset --soft HEAD~1 | | Wrong files committed, want to re-stage | git reset HEAD~1 (mixed) | | Changes were a mistake, delete them | git reset --hard HEAD~1 | | Just wrong message / forgot a file | git commit --amend | | Commit is already pushed/shared | git revert <hash> | | "I lost a commit!" | git reflog then reset to its hash |

The whole trick is asking "is it shared?" first, then "do I want to keep the changes?" second. Answer those two and there's exactly one right command — no guessing, no making it worse.

Frequently asked questions

How do I undo my last Git commit but keep the changes?

Run git reset --soft HEAD~1. It removes the commit but leaves your changes staged, ready to re-commit. Use the default git reset HEAD~1 (mixed) if you want the changes kept but unstaged.

What's the difference between git reset and git revert?

reset rewrites history by moving your branch pointer back — safe only for local, unpushed commits. revert adds a new commit that undoes a previous one, leaving history intact — the correct choice for commits already pushed to a shared branch.

Can I recover a commit after git reset --hard?

Usually yes. Run git reflog to find the lost commit's hash (Git keeps it for about 90 days), then git reset --hard <hash> to restore it.

Written by Yash Thakur

Senior React Developer · 8+ years building for the web

More articles

Keep reading