Git: How To Revert A Branch Merge

This was a stumper for me a while back. Jason Meridth posted on reseting / reverting git commits and I had a question in the comments. My specific situation was about having a branch merged at the wrong time and how to undo that merge. Here’s an example of the situation, shown with gitk:

image

In this scenario, the “test” branch was not supposed to be merged yet… i missed some changed, or i needed to do something else with the master branch, etc. Whatever the reason, I wanted to rollback to the point where test and master were not yet merged. As i stated in the comments on jason’s post, I ran around in circles trying to get ‘git revert’ to do what I wanted, with no luck. Lucky for me, Nick Quranto had a blog post on reverting with git, pointed me toward an in-depth read on the subject and was happy to answer my questions via email.

It turned out the answer was much more simple than what I was trying to do. Since I merged the test branch into the master branch, I can run this from the master branch:

   1: git reset --hard HEAD^

Here, you can see that this moves the HEAD of master back to the previous commit (Note: for more info on what HEAD^ means, see Git Treeishes in the git docs):

image

Apparently the “revert” command differs from the “reset” command in a very important way: revert will take the changes from whatever commit you specify and undo them, creating a new commit for the new version. In contrast to that, “reset” will move the pointer that represents your branch’s location to whatever point you specify. So, doing a reset on the test master branch allowed me to move the current location of HEAD back to the previous commit on that branch (Another Note: I know I’m messing up the detail on how reset vs. revert works… this is just a basic high level experience report, rather than an in-depth discussion on what really goes on).

The result looks like this in gitk:

image

This is exactly what I wanted: the master and test branch are no longer merged and I can continue working on either / both of them independently with the ability to merge them together at some later point in time.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Branching Strategies, Git, Source Control. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Ahh, glad you got it figured out. git reset –head HEAD^ works great if you haven’t pushed the merge out. Otherwise you’re stuck with reverting it or looking into that lengthy post from Linus. :)

  • Hi Derick,
    Just to let you know your link to the article by Linus Torvalds should be changed to: http://www.kernel.org/pub/software/scm/git/docs/v1.6.3.2/howto/revert-a-faulty-merge.txt

  • Salsan Jose

    How to detach all of the merges of a particular branch in one try?