0

Sometimes I want to split my latest work on a branch into a new branch.

# Create a new branch tracking the old branch
git branch -t new-branch

# Reset the old branch to a prior commit
git reset --hard HEAD~3

git checkout new-branch

I expect git rebase to now do nothing, because the docs say:

All changes made by commits in the current branch but that are not in <upstream>
are saved to a temporary area. This is the same set of commits that would be shown
by git log <upstream>..HEAD; or by git log 'fork_point'..HEAD, if --fork-point is
active (see the description on --fork-point below)....

So new-branch is reset to old-branch, and any saved changes are applied. Shouldn't those saved changes include the commits new-branch pointed to that were no longer reachable from old-branch?

Instead, new-branch is reset to old-branch and the commits disappear.

mgiuffrida
  • 3,299
  • 1
  • 26
  • 27

1 Answers1

0

Reading the docs more closely, I found:

   If <upstream> is not specified, the upstream configured in branch.<name>.remote
   and branch.<name>.merge options will be used (see git-config(1) for details) and
   the --fork-point option is assumed.

So instead of using the commits from <upstream>..HEAD, the rebase will use fork_point..HEAD. And here's what fork_point is:

git merge-base --fork-point <upstream> <branch>

merge-base is complicated, but in this case it checks the reflog and realizes the "new" commits previously existed in the branch we branched from, and returns the same commit as new-branch, which is also HEAD, so git log fork_point..HEAD returns nothing. Then the rebase doesn't end up saving and applying the new commits.

This is explained in more detail, along with a better way to achieve the new branch, in John Mellor's answer.

Community
  • 1
  • 1
mgiuffrida
  • 3,299
  • 1
  • 26
  • 27
  • Equivalently (but you have to *remember* this), you can use `--no-fork-point` when rebasing later, or be explicit about the local branch upon which you're rebasing even if it's already set as the upstream. It's basically a very bad consequence of the sneaky automatic `--fork-point` code, which was a cool (or "kewl"?) idea way back when but turns out to be more trouble than it's worth, in my opinion. :-) – torek Mar 24 '17 at 01:33
  • (Also, I edited the accepted / community-wiki answer to the original question to add the warning.) – torek Mar 24 '17 at 01:46