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 56 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 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 →Always fixableHow 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 →Usually recoverableMy rebase went wrong and my commits are gone — how do I get them back?
The pre-rebase commits are still in the object database. git reflog shows the position from before the rebase started, and ORIG_HEAD is a shortcut to it — git reset --hard ORIG_HEAD usually restores everything in one command.
Read the fix →