Undo a commit you already pushed
How do I undo a commit that's already on the remote?
Short answer
On a shared branch, use git revert <hash> — it adds a new commit that reverses the change, so nobody else has to do anything. Rewriting with reset plus a force-push is only appropriate on a branch you're certain nobody else has pulled.
git revert a1b2c3d
git push
Safely undoes a pushed commit by adding an inverse commit
Does this match your situation?
- You pushed a commit that broke the build or shipped the wrong change.
- Others may have already pulled the commit.
- You need the change gone from the branch without breaking anyone's clone.
Step-by-step fix
Find the commit you want to undo
Get the hash and double-check the diff. Reverting the wrong commit creates a second problem on top of the first.
step 1git log --oneline -10 git show a1b2c3dRevert it — the safe option for shared branches
Revert computes the inverse of that commit's diff and commits it. History stays intact, the bad change is neutralised, and everyone else just pulls normally.
step 2git revert a1b2c3d git pushReverting several commits: git revert --no-commit a1b2c3d f4e5d6c && git commit -m "Revert broken feature"
Reverting a merge commit needs -m
A merge commit has two parents, so Git can't tell which side you want to keep. -m 1 means 'treat the first parent as the mainline', which is what you want when undoing a feature merged into main.
step 3git revert -m 1 a1b2c3dRewriting instead — only on branches you own
If you're certain the branch is yours alone, you can drop the commit entirely and force-push. --force-with-lease refuses if anyone else has pushed since you last fetched, which plain --force would happily overwrite.
step 4git reset --hard HEAD~1 git push --force-with-leaseNever do this on main, or on any branch a teammate might have pulled.
Why this works
Git's distributed model means every clone holds the full history, so 'undoing' a shared commit isn't a single authoritative action — it's a change that has to propagate. Revert works because it only adds: everyone's existing commits stay valid and a plain pull brings in the fix. Rewriting removes commits others may already have, leaving their branch pointing at objects the server no longer acknowledges, and their next push tries to restore the very commit you deleted.
How to stop it happening again
- Protect main with branch rules requiring pull requests and passing CI.
- Push feature branches, not commits straight to main.
- Run tests locally or via a pre-push hook before pushing.
Commands used in this guide
Still stuck?
Search the full command reference and every other rescue guide — there are 76 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
Should I revert or force-push to undo a pushed commit?
Revert on any branch other people use — it's additive and requires nothing from them. Force-push only on a branch you're certain is exclusively yours, and always use --force-with-lease so the push aborts if someone else has pushed in the meantime.
How do I revert a merge commit?
git revert -m 1 <merge-hash>. The -m flag names which parent is the mainline; 1 is the branch you merged into, which is almost always what you want. Without it, Git refuses because it cannot guess which side to undo.
Does git revert delete the original commit?
No, and that's the point. The original stays in history and a new commit is added that applies the exact opposite change. Anyone can still inspect what happened, and nobody's clone is invalidated.
Related rescue guides
How do I undo the last commit but keep my work?
git reset --soft HEAD~1 removes the commit and leaves every change staged, ready to recommit. Use --mixed (the default) if you also want the changes unstaged, and only use --hard if you genuinely want the work destroyed. If the commit is already pushed, revert it instead of resetting.
Read the fix →Always fixableI reverted a merge, fixed the branch, and now merging it again brings back nothing — why?
Git thinks the branch is already merged, because it is — the merge commit is still in history, and the revert only undid its content. Revert the revert (git revert <revert-commit>) before merging again, or rebase the feature branch onto main so its commits get new identities.
Read the fix →Usually recoverableI ran git commit --amend and destroyed the previous commit — can I get it back?
Amend does not edit a commit, it replaces it — and the original is still in the object database, listed in the reflog. git reset --soft HEAD@{1} puts you back on it with your changes staged, and git reflog shows every version so you can pick the one you want.
Read the fix →Usually recoverableSomeone force-pushed and my commits are gone — how do I get them back?
Your local clone still has the commits, and your reflog records where the branch pointed before the force-push overwrote it. Find that hash with git reflog, recover it to a branch, and push it back. If your local copy is already clean, a teammate's clone or the server's reflog may still have it.
Read the fix →