To undo the last git commit and keep your changes staged, run git reset --soft HEAD~1. If the commit has already been pushed to a shared branch, use git revert HEAD instead, which creates a new commit that reverses it without rewriting history.
git reset --soft HEAD~1
That’s the answer most people need. The rest of this post explains which option to choose, because they behave very differently.
Which command should you use?
- Commit not pushed, want to keep the changes:
git reset --soft HEAD~1orgit reset HEAD~1 - Commit not pushed, want to throw the changes away:
git reset --hard HEAD~1 - Commit already pushed and shared:
git revert HEAD - Just need to fix the message or add a forgotten file:
git commit --amend
HEAD~1 means “one commit before HEAD”. Use HEAD~3 to go back three commits.
git reset –soft: undo the commit, keep everything staged
Soft reset moves your branch back one commit but leaves the changes in the staging area, exactly as they were just before you committed. It’s ideal when you committed too early or want to split the work into smaller commits.
git reset –mixed: undo the commit and unstage
git reset HEAD~1
Mixed is the default mode, so --mixed is optional. Your changes stay in the working directory but are no longer staged, so you can review and re-add them selectively with git add -p.
git reset –hard: undo the commit and discard the changes
git reset --hard HEAD~1
Hard reset moves the branch back and wipes the changes from both the staging area and your working files. Any uncommitted work in the working directory goes too. Use it only when you’re sure you don’t want any of it.
If you regret a hard reset, the commit isn’t immediately gone. git reflog lists where HEAD has been, and you can get back with git reset --hard <hash> using the hash from that list. Uncommitted changes wiped by a hard reset, however, can’t be recovered this way.
git revert: undo a commit that’s already pushed
git revert HEAD
Revert doesn’t remove anything. It creates a new commit that applies the exact opposite of the target commit, then you push it like any other commit. History stays intact, so nobody else’s clone is disrupted. This is the right choice for main or any branch other people have pulled.
To revert an older commit, pass its hash: git revert <hash>. Reverting a merge commit needs -m 1 to tell Git which parent to keep.
git commit –amend: fix the last commit instead
git commit --amend -m "Better commit message"
If the commit is basically right but the message is wrong or you forgot a file, stage the missing file and run git commit --amend. To keep the original message, add --no-edit. Amend replaces the last commit with a new one, so it rewrites history just like reset does.
Gotchas
- Don’t rewrite pushed history on shared branches. Reset and amend change commit hashes. If you’ve already pushed, you’d need
git push --force-with-lease, which can disrupt collaborators. Prefer revert. - On your own feature branch, force-pushing after a reset is usually fine.
--force-with-leaseis safer than--forcebecause it refuses to overwrite commits you haven’t seen. - Check before a hard reset. Run
git statusandgit stashanything you want to keep. Our git stash explained guide covers that. - Undoing the very first commit doesn’t work with
HEAD~1because there’s no parent.git update-ref -d HEADremoves it while keeping your files.
Prefer a visual tool?
Most Git GUIs offer “undo last commit” or reset options from a right-click menu, which makes the soft/mixed/hard choice clearer. See our roundup of the best Git UI clients for 2026, or try lazygit if you’d rather stay in the terminal.
More quick Git answers
- Git detached HEAD: what it means and how to fix it
- How to rename a Git branch locally and on the remote
- How to set up SSH keys for GitHub
- Git stash explained
- How to view and change remote origins in Git

Leave a Reply
You must be logged in to post a comment.