Categories
git git-merge undo

Undo a Git merge that hasn’t been pushed yet

4620

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?

6

5258

With git reflog check which commit is one prior the merge (git reflog will be a better option than git log). Then you can reset it using:

git reset --hard commit_sha

There’s also another way:

git reset --hard HEAD~1

It will get you back 1 commit.

Be aware that any modified and uncommitted/unstashed files will be reset to their unmodified state. To keep them either stash changes away or see --merge option below.


As @Velmont suggested below in his answer, in this direct case using:

git reset --hard ORIG_HEAD

might yield better results, as it should preserve your changes. ORIG_HEAD will point to a commit directly before merge has occurred, so you don’t have to hunt for it yourself.


A further tip is to use the --merge switch instead of --hard since it doesn’t reset files unnecessarily:

git reset --merge ORIG_HEAD

–merge

Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added).

32

  • 145

    I don’t think this will (always?) work — the “one prior the merge” will be the most recent commit that was merged in from the other branch — it won’t be the most recent commit on the current branch. Right? (This might just be a result of what git log chooses to show by default — maybe there is a different output of git log or git reflog could be used for this)

    Jan 14, 2011 at 18:12


  • 6

    I think it might depend whether you squash merge.

    Jan 15, 2011 at 12:45

  • 32

    @JohnBachir is right. In the git log output, you want to look at the two parent commits. One is the latest commit in your branch, one is the latest commit in the branch you merged into. You want to git reset --hard to the parent commit on the branch you merged into.

    – Justin

    Oct 12, 2011 at 20:21

  • 7

    @JohnBachir: As long as the “merge” isn’t really a fast forward, it will result in a new commit that is at the top of the log, and this commit has two parents (or more than 2 if you do an octopus merge). If you remove this one merge commit, then all of the older commits that came in from the merge will disappear, too. To be safe, though, after a reset git will tell you where the new head is: “HEAD is now at 88a04de <commit message>”. I always look at that to make sure that I ended up where I expected to be. My project uses a standard branch naming scheme to keep things memorable.

    Nov 21, 2011 at 16:36

  • 52

    What i found useful was to look at “git reflog” and look for the last commit that i did in master. Then do git reset --hard <commit_sha>

    Dec 5, 2012 at 16:53

1623

Assuming your local master was not ahead of origin/master, you should be able to do

git reset --hard origin/master

Then your local master branch should look identical to origin/master.

12

  • 79

    @Carter it actually is not the best answer. It is possible that origin/master may be ahead of your local master just previous to the merge by some commits, in that case this might not give the desired results

    Jun 22, 2011 at 14:55

  • 16

    @dhruva-sagar Yes, but as long as git doesn’t say you’re behind, and you don’t fetch, you should be fine.

    – Kelvin

    Dec 15, 2011 at 17:10

  • 3

    Thanks! This is perfect if (and only if) you have a remote repository.

    – tomc

    Jan 31, 2013 at 10:59

  • 2

    No it’s not the perfect one for this question, see the “assume” clause. MBO’s answer actually covers this case, and the case where the merge is not the only local commit.

    – inger

    Mar 21, 2013 at 14:29


  • 2

    Once again, maybe this warning should go into the answer itself: Always avoid rewriting git history!

    – cregox

    Sep 17, 2013 at 20:18

1227

See chapter 4 in the Git book and the original post by Linus Torvalds.

To undo a merge that was already pushed:

git revert -m 1 commit_hash

Be sure to revert the revert if you’re committing the branch again, like Linus said.

6

  • 10

    @perfectionist agreed 🙂 Kind of wish there was a way to migrate this answer to another question– (maybe there is?)

    Apr 16, 2013 at 23:04

  • for more information about revert: link

    – assaqqaf

    Mar 4, 2014 at 2:22

  • 3

    To be confident that this revert has worked, you can do git diff hash1 hash2 where hash1 is the committed revert, and hash2 is the old commit whose state you were trying to get back to. No output == success! I was able to roll back multiple commits by doing this multiple times, starting by reverting the most recent merge and working backwards. git diff showed me that I ended up in the state I wanted.

    May 6, 2014 at 9:41


  • 7

    Notice that this does not actually solve the original poster’s question. The original poster already used git revert -m 1 <commit>. The problem is that doing that doesn’t erase the accidental merge that he did (and hasn’t pushed yet). The other answers involving hard resets are better for the original poster’s problem.

    – user456814

    Jul 5, 2014 at 18:12

  • This is a great resource straight from Github: How to undo (almost) anything with Git

    Feb 3, 2017 at 21:16