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 56 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 fixableHow do I undo a Git merge?
If the merge hasn't been pushed, git reset --hard HEAD~1 removes it cleanly. If it has been pushed, use git revert -m 1 <merge-hash> so history stays valid for everyone else. And if you're still in the middle of a conflicted merge, git merge --abort is all you need.
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 →Always fixableI committed a secret — how do I remove it from Git history?
Rotate the secret first — that's the only step that genuinely protects you. Then purge it from history with git filter-repo (or the BFG Repo-Cleaner) and force-push. Deleting the file in a new commit does nothing, because the old commit still contains it and is still fetchable.
Read the fix →