Undo a merge — before or after pushing
How do I undo a Git merge?
Short answer
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.
git reset --hard HEAD~1
Removes an unpushed merge commit and returns to the pre-merge state
Does this match your situation?
- You merged the wrong branch, or merged too early.
- A merge brought in changes that broke everything.
- You're stuck mid-merge with conflicts you don't want to resolve.
Step-by-step fix
Still mid-merge? Just abort
If the merge hasn't completed — conflicts are unresolved and no merge commit exists yet — abort is the clean exit. It restores everything to the moment before you started.
step 1git merge --abortMerge completed but not pushed: reset
A merge commit is just a commit with two parents, so moving the branch pointer back one step removes it. Confirm the merge is the most recent commit first.
step 2git log --oneline -3 git reset --hard HEAD~1Check git log first — if you've committed since the merge, HEAD~1 isn't the merge.
Already pushed: revert with -m
Reverting a merge requires telling Git which parent is the mainline. -m 1 means the branch you merged into, which is the usual intent. This adds a commit undoing everything the merge brought in.
step 3git revert -m 1 a1b2c3d git pushKnow the catch before you re-merge later
Once you revert a merge, Git considers that branch already merged, so a later attempt to merge it again brings in nothing. You need to revert the revert to bring the changes back.
step 4git revert <hash-of-the-revert-commit> git merge feature/balanceThis trips up a lot of teams. Reverting a merge undoes the changes but not the merge relationship.
Why this works
A merge commit records two parents, which is how Git knows the branches have been combined. Resetting past it removes that record entirely, so the branch looks as if the merge never happened and a future merge behaves normally. Reverting keeps the merge commit — and therefore the 'already merged' relationship — while adding a commit that cancels its content. That asymmetry is exactly why re-merging after a revert appears to do nothing, and why you have to revert the revert to bring the work back.
How to stop it happening again
- Preview a merge before committing to it: git merge --no-commit --no-ff, inspect, then git merge --abort if you don't like it.
- See what a branch would bring in with git diff main...feature before merging.
- Require pull requests with CI on protected branches so bad merges never reach main.
Commands used in this guide
git mergeCombine another branch's history into the current one.
git resetMove the current branch pointer, optionally rewriting the index and your files.
git revertCreate a new commit that undoes an earlier one, leaving history intact.
git reflogThe undo history for everything - the single most important recovery command.
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
How do I undo a merge that hasn't been pushed?
git reset --hard HEAD~1, assuming the merge commit is the most recent one. This discards the merge commit and returns your branch to its pre-merge state. Check git log --oneline first to confirm nothing was committed after the merge.
How do I undo a merge that has already been pushed?
git revert -m 1 <merge-commit-hash>, then push. This adds a new commit undoing the merged changes without rewriting history, so nobody else's clone breaks.
Why doesn't re-merging work after I reverted a merge?
Because the merge commit is still in history, Git considers those commits already merged and has nothing new to bring in. To get the changes back, revert the revert commit — then the branch can be merged normally again.
Related rescue guides
Git says I have merge conflicts — how do I fix them?
Git pauses and marks the clashing sections with <<<<<<<, ======= and >>>>>>>. Edit each file to the version you actually want, delete the markers, git add the file, then git merge --continue. If it gets overwhelming, git merge --abort returns you to exactly where you started.
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 →Always fixableGit says 'You have not concluded your merge (MERGE_HEAD exists)' — how do I get unstuck?
A merge you started is still open. Decide one of two things: finish it by staging the resolved files and committing, or throw it away with git merge --abort. Everything else is blocked until you do, because Git will not start a second operation on top of an unfinished one.
Read the fix →Always fixableHow do I undo a commit that's already on the remote?
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.
Read the fix →