Push & pull problemsAlways fixable

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.

quick fix
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

  1. 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 1
    git log --oneline -10
    git show a1b2c3d
    
  2. Revert 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 2
    git revert a1b2c3d
    git push
    

    Reverting several commits: git revert --no-commit a1b2c3d f4e5d6c && git commit -m "Revert broken feature"

  3. 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 3
    git revert -m 1 a1b2c3d
    
  4. Rewriting 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 4
    git reset --hard HEAD~1
    git push --force-with-lease
    

    Never 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

git revert

Create a new commit that undoes an earlier one, leaving history intact.

git reset

Move the current branch pointer, optionally rewriting the index and your files.

git push

Upload your commits to the remote repository.

git log

Browse commit history with as much or as little detail as you want.

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

← All Git Rescue guides