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

Always fixable

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 fixable

I 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 recoverable

I 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 recoverable

Someone 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 →
← All Git Rescue guides