Undo a fast-forward git merge

A friend has a fork of my project and sent me a pull-request. Without doing any eyeballing at all, I did this:


$ git fetch XXX
$ git merge XXX/master

Git ran a fast-forward merge and now all those commits are in my code. Then I ran some tests and KABOOM.

After spending a while digging around and seeing just how much needed to be fixed, I decided that it would be better to just send an email with the test errors back to my friend rather than try to fix them myself. I got my own work to do, after all.

So I sent the email, but now I had a git checkout with all those commits.

And since this was a fast-forward merge, git didn’t create a commit for the merge.

Incidentally, today I learned that you can force git to make an explicit commit for fast-forward merges like this:


$ git merge --no-ff XXX/master

I went to #git on irc.freenode.org, where I always go, and I explained the situation, and then was told to do these commands:


$ git reflog show master
$ git reset --keep master@{1}

And it worked! All the foreign commits are now gone.

But what just happened?

I’m not absolutely certain, but it seems like the git reflog show master command shows the changes applied to HEAD over time. This is what the top lines showed for me:


cce8252 master@{0}: merge XXX/master: Fast-forward
08c8f50 master@{1}: commit: Cleaning up the my-account pages
5526212 master@{2}: commit: Deleted a handler that was never getting used

This is different than git log. This is talking about the state of my local master branch over time.

Then, the next command git reset –keep master@{1} is telling git to reset the checkout to look like what master looked like one state in the past.

Like I said, I’m still not sure I understand this, but I plan to study it more.

  • Nick W.

    Matt,

    Hope you are well. Great collection of posts on this blog.

    Off topic, I thought you might be interested in this website pinterest.com, which utilizes Python. (One of the site's cofounders is a former coworker of mine.)

    Best regards to you and your family,
    Nick

  • http://blog.tplus1.com Matt Wilson

    Hey Nick!

    So good to hear from you.

    pinterest is going to be freakin' huge. I know that because several women I know all are obsessed with it, and none of them know each other.

    What are you up to these days? Let's catch up.

    Matt

  • Joe

    Did you ever figure this out yet? 

    HGH
    HGH Blog
    Genf20

  • http://blog.tplus1.com Matt Wilson

    Yeah, are you having trouble with it?

  • http://biekei.com Biekei Ojo

    great. explained two things ( forcing git to commit a FF and how to revert a fault FF commit). thanks man

  • Ian Cumings

    This just saved me – many thanks!

  • http://blog.tplus1.com Matt Wilson

    That's great! Glad to help.

  • http://twitter.com/ScriptFanix Vincent Riquer

    Thanks!
    Also, add
    [merge]
    ff = false

    to your git configuration to make this the default.

  • http://blog.tplus1.com Matt Wilson

    Didn’t know that configuration trick! Thanks so much for passing that along.

  • Geoff

    for newbies like me who could not find the .gitconfig file, here is the Git Bash command equivalent:

    git config –global merge.ff false

    Thanks!!

  • Raif

    sweet jesus. I know that git “never looses your data” but I couldn’t find it for the life of me. this command showed me just the right commit to reset to. Thanks.

  • http://blog.tplus1.com Matt Wilson

    Great! Glad it helped