NeuroAgent

Complete Guide to Undoing Git Merge

Step-by-step guide to undoing unpushed Git merges. Discover safe methods using git reset, git revert, and more to restore your repository.

Question

How to undo a Git merge that hasn’t been pushed yet

I accidentally ran git merge some_other_branch on my local master branch. I haven’t pushed the changes to origin master. How do I undo the merge?

After merging, git status says:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

How do I undo all these commits?

NeuroAgent

To undo a Git merge that hasn’t been pushed yet, you can use git reset --hard ORIG_HEAD which will reset your repository to the state before the merge operation, effectively removing all the merge commits. This is the most straightforward method when you haven’t made any additional changes after the merge and want to completely undo the merge action. Another approach is using git revert which creates a new commit to reverse the merge changes while preserving the commit history.

Contents

Understanding Your Current Git State

When you run git merge some_other_branch, Git creates a new merge commit that combines the changes from both branches. In your case, this merge commit along with any additional commits made during the merge process have brought your local master branch 5 commits ahead of origin/master.

The key information here is that none of these changes have been pushed to the remote repository, which means you have full flexibility in how to handle this situation locally without affecting other collaborators.

ORIG_HEAD is a special reference that Git automatically creates before performing potentially dangerous operations like merges, rebases, or resets. It always points to where your HEAD was before the operation began.

This makes ORIG_HEAD particularly useful for undoing operations, as it gives you a reliable reference point to return to the previous state.

Primary Method: Using git reset --hard ORIG_HEAD

The git reset --hard ORIG_HEAD command is the most direct and effective way to undo an unpushed merge. This command:

  • Resets your HEAD pointer to where it was before the merge
  • Resets the index (staging area) to match that commit
  • Resets your working directory to match that commit
bash
git reset --hard ORIG_HEAD

As explained in the Stack Overflow discussion, this command “simply reset the state of the repository back to how it was before the merge.” This is exactly what you need to undo your accidental merge.

The --hard option is important here because it ensures that all the changes introduced by the merge are completely discarded from your working directory, not just from the commit history.

Alternative Methods for Undoing Merges

Using git revert

If you want to preserve the merge commit in your history but undo its effects, you can use git revert:

bash
git revert -m 1 <merge-commit-hash>

The -m 1 option tells Git to revert the changes as they appeared in the first parent of the merge commit (typically the branch you were on before merging).

As Squash.io explains, “Unlike git reset, git revert creates a new commit that undoes the changes made in the merge commit. This method is useful if you want to preserve the merge commit’s history while still removing its changes.”

Using git reset --merge

For a safer reset that preserves uncommitted changes, you can use:

bash
git reset --merge ORIG_HEAD

As noted in LinuxHint, “the ‘–merge’ option keeps the changes in the working directory but resets the index and HEAD to the ORIG_HEAD position.”

Step-by-Step Guide to Undo Your Merge

Here’s the complete process to undo your merge:

  1. Verify your current state:

    bash
    git log --oneline -5
    git status
    
  2. Check what ORIG_HEAD points to:

    bash
    cat .git/ORIG_HEAD
    
  3. Undo the merge using the primary method:

    bash
    git reset --hard ORIG_HEAD
    
  4. Verify the undo was successful:

    bash
    git log --oneline -5
    git status
    
  5. If needed, re-merge properly:

    bash
    git merge some_other_branch
    

This process will completely remove the merge commits and return your repository to the exact state it was in before you ran the merge command.


Important Considerations and Warnings

Warning: Data Loss Risk

The git reset --hard ORIG_HEAD command is destructive and will permanently discard any changes you made to your working directory after the merge. If you have uncommitted changes that you want to keep, use git reset --merge ORIG_HEAD instead.

As the official Git documentation warns, “Running git reset --hard ORIG_HEAD will let you go back to where you were, but it will discard your local changes, which you do not want.”

Check for uncommitted changes

Before running the reset command, check if you have any uncommitted changes:

bash
git status

If you see uncommitted changes that you want to preserve:

  1. Either stash them first:

    bash
    git stash
    git reset --hard ORIG_HEAD
    git stash pop
    
  2. Or use the safer --merge option:

    bash
    git reset --merge ORIG_HEAD
    

ORIG_HEAD availability

ORIG_HEAD is only available immediately after a merge operation. If you’ve performed other operations (like additional commits) since the merge, ORIG_HEAD might not be available or might point to an unexpected location.

What to Do After Undoing the Merge

Once you’ve successfully undone the merge, you can:

  1. Inspect the changes you were trying to merge:

    bash
    git log some_other_branch --oneline
    git diff master...some_other_branch
    
  2. Perform a more careful merge:

    bash
    git merge --no-commit some_other_branch
    # Review changes
    git commit -m "Proper merge message"
    
  3. Or use a different approach:

    • Consider merging with --no-ff to preserve branch history
    • Use git cherry-pick to select specific commits
    • Rebase the branch before merging

Remember that since you haven’t pushed these changes to the remote repository, you have complete freedom to experiment with different approaches without affecting other team members.

Conclusion

Undoing an unpushed Git merge is straightforward when you use the right approach. The key takeaways are:

  1. git reset --hard ORIG_HEAD is the most direct method to completely undo an unpushed merge and return to the pre-merge state.

  2. Always check for uncommitted changes before using --hard reset to avoid losing important work.

  3. git revert is an alternative if you want to preserve the merge commit in history while undoing its effects.

  4. Verify your actions by checking git status and log after undoing the merge to ensure you’re back to the expected state.

  5. Learn from the experience by being more careful with merge operations, perhaps using git merge --no-commit first to review changes before committing.

By following these steps, you can confidently undo accidental merges and continue with your development workflow without losing important work or affecting your remote repository.

Sources

  1. Undo a Git merge that hasn’t been pushed yet - Stack Overflow
  2. How to undo a merge in Git | Learn Version Control with Git
  3. Undo an unpushed Git merge | Sentry
  4. Undo a Git Merge That Hasn’t Been Pushed Yet | Squash.io
  5. Git - git-reset Documentation
  6. Undo a Git Merge That Hasn’t Been Pushed Yet | LinuxHint
  7. Undoing in Git - Tratif
  8. The Ultimate Guide to Reverting Git Merges · seymour.co.za