Ctrl K

Undo the Last Commit and Keep the Changes

Use git reset --mixed HEAD~1 to remove the last commit while keeping its changes in the working tree, ready to fix and re-commit.

Use this when the last commit was premature - wrong files staged, a typo in the change, or work committed too early - and you want the commit gone but the changes kept. git reset --mixed moves the branch back one commit and leaves all of that commit's changes in the working tree as unstaged modifications, so you can adjust and commit again.

Undo the last commit

git reset --mixed HEAD~1

HEAD~1 means "one commit before the current HEAD", so the branch pointer moves back one commit. --mixed is the default mode, so git reset HEAD~1 does the same thing.

Verify

The commit is gone from the log and its changes now show as unstaged modifications.

git log --oneline -3   # the undone commit no longer appears
git status             # its changes are back as modified / untracked files

Nothing is lost: the file contents are exactly what they were after the commit, only the commit itself and the staging are undone.

Fix and re-commit

Edit whatever needed fixing, then stage and commit again as usual.

git add <files>
git commit -m "corrected commit"

The three reset modes

All three move the branch pointer back; they differ in what happens to the changes.

git reset --soft HEAD~1    # keep changes AND keep them staged
git reset --mixed HEAD~1   # keep changes, unstaged (default)
git reset --hard HEAD~1    # discard the changes entirely - destructive

--soft is handy when the changes were fine and only the commit message or grouping was wrong. --hard permanently discards the commit's changes from the working tree, so use it only when you are sure the work is unwanted.

Only for unpushed commits

Reset rewrites history, so this workflow is for commits that have not been pushed yet. If the commit is already on the remote, resetting locally makes your branch diverge and the next push gets rejected. For a pushed commit, prefer a revert, which undoes the change as a new commit without rewriting history:

git revert <commit-hash>