Why is git rebase discarding my commits?

This has bitten me at least a dozen times after a certain git upgrade. There is now a difference between git rebase and git rebase master: the former was changed to use same fancy "fork-point" machinery. There is a detailed explanation in answer to this question:

  • Understanding "git pull --rebase" vs "git rebase"

Today for the first time I figured out concrete steps to reproduce it.

MY SCENARIO: I have 4 commits on master which I've decided should now move into a topic branch, plus I want to reorder them. If I do it this way...

  1. Create a new topic branch, tracking the current branch (master)

    git checkout -b topic -t
    
  2. Rewind master back :

    git checkout master
    git reset --hard origin/master
    
  3. Reorder the commits on topic

    git checkout topic
    git status  # "Your branch is ahead of 'master' by 4 commits" Good!
    git rebase --interactive
    

... then the interactive rebase screen comes up with this ominous list of commits:

    # no-op

Uh-oh... I save the file and continue anyway. Yup, looks like git's thrown away my work again. topic now points to the same commit as master and origin/master.

So I presume what triggered this for you is:

  1. upgrading git

  2. You had done something like my step 2 on your master branch.

In my lay-man's understanding, the fork-point machinery searches back through the reflog and notices that those commits had been removed from the upstream branch, and comes to the conclusion that to bring your topic branch "up to date" they should be removed there too.

The solution is, instead of:

git rebase

Use one of:

git rebase --no-fork-point
git rebase master

But I suspect like me you wouldn't do this every time. (I mean, we set an upstream branch for a reason, right?) So you'd just learn to recognise when this disaster strikes, use git reflog and git reset --hard to recover, and then use the above command.

Still, you need to be careful now - I think this is extremely dangerous. I have had times when I've rebased a large branch and a few commits silently disappeared from the beginning, and I didn't notice for days! I'm fairly comfortable mining git reflog to do disaster recovery, but I'm not sure everyone is. I wonder if git has started being too clever here.

Tags:

Git

Git Rebase