How do you undo the last Git commit?

Git · History & Undo · updated 2026-08-23

git reset --hard HEAD~1 — Undo last commit

git reset --hard HEAD~1 removes the last commit and discards its changes from the working tree. If you want to keep the changes as uncommitted edits, use the same command without --hard.

The --soft flag is what makes this undo safe: your files and the staging area are untouched, only the branch pointer moves back one commit. Use --mixed (the default) to also unstage, and reserve --hard for when you genuinely want the working tree reset too - that one discards changes.

If the commit was already pushed, resetting rewrites history that others may have pulled; git revert HEAD creates a new commit that undoes the old one instead, which is the collaboration-safe route on shared branches.

Related Git shortcuts: History & Undo

ShortcutActionNotes
git logCommit historyShow commit history.
git log --onelineOne-line logShow commits in one-line format.
git diffShow diffShow unstaged changes.
git reset HEAD [file]UnstageUnstage a staged file.
git reset --hard HEAD~1Undo last commitCompletely undo the last commit.
git stashStash changesTemporarily save current changes.
git stash popApply stashRestore stashed changes.
git cherry-pick [hash]Cherry-pickApply a specific commit to current branch.

From the Git reference (24 entries) · all how-to answers

Keeping or discarding the changes

git reset --soft HEAD~1 removes the commit but keeps its changes staged, ready to recommit with a better message or split into several commits; git reset HEAD~1 (mixed, the default) keeps them as unstaged edits; --hard throws them away. Choose by what you want to happen to the work, not by habit — hard reset is the one that loses code.

If the commit was already pushed

Resetting a pushed commit rewrites history that others may have fetched, and force-pushing over it breaks their branches. On a shared branch use git revert HEAD instead, which adds a new commit that undoes the last one and keeps history intact. On a personal branch with an open pull request, reset plus git push --force-with-lease is acceptable and refuses to overwrite work you have not seen.

Recovering after a mistake

A commit removed by reset still exists for a while: git reflog lists where HEAD has been, and git reset --hard HEAD@{1} (or the commit hash from the reflog) brings it back. This is the safety net that makes reset less frightening than it looks — as long as the changes were committed at some point.