0

I have the following commit history:

* c742f81 (HEAD -> new_feature) x8
* 1869290 x7
* 697809b x6
*   a61e55c x5
|\  
| * da890d6 (master) n6
| * ccc8f5e n5
| * 0095064 n4
| * 002ab13 n3
| * cb93dc4 m4
| * ccaa631 m3
* | 714da58 x4
* | ea11b0d x3
* | 66f1582 x2
* | 3e96100 x1
|/  
* 4f46723 m2
* ce576e8 1

As you can see, I have master branch on n6 and new_feature branch on x8. I run git rebase -i master new_feature and I got this:

pick 3e96100 x1
pick 66f1582 x2
pick ea11b0d x3
pick 714da58 x4
pick 697809b x6
pick 1869290 x7
pick c742f81 x8
Rebase `da890d6..c742f81` onto `714da58` (7 commands)

Now, why I am getting 714da58 ? Should not it be da890d6 ? Also, where is x5 (Git should rebase the commits that were merged in x5)?

Number945
  • 4,631
  • 8
  • 45
  • 83
  • When you rebase going back beyond a merge commit, in general Git will ignore the merges and won't attempt to redo them. Rebasing in this case might not be the best option. – Tim Biegeleisen Nov 01 '19 at 13:00

2 Answers2

1

What you've told Git to do in this case is to take new_feature and rebase (replay) it on top of master. What Git is showing you is the commits which will be placed on top of master.

You see x1 through x4 in this case because they're on new_feature but not on master and you told Git you wanted to replay all such commits onto master. You don't see n6 because it's not going to be rebased: it's already on master. You're missing x5 because git rebase by default does not replay merges. In this case, this makes sense, because the merge wouldn't introduce anything new.

You can, however, recreate the merge if you want by using the --rebase-merges option to git rebase; doing so requires a relatively recent Git version.

You see the 714da58 entry because Git can end up using the reflog as a basis for finding a better common ancestor; this is documented in the --fork-point option. This doesn't always produce a "logical" sounding commit, but it usually does produce a better rebase. Probably at some point your branch was at 714da58, which is also not common to both branches.

bk2204
  • 64,793
  • 6
  • 84
  • 100
  • my question is if not `n6` then why `714da58` ? – Number945 Nov 01 '19 at 13:52
  • The command you typed is `rebase -i master new_feature` which means rebase branch new-feature on top of branch master. The commits that need to be "rebased" are the ones on new_feature, but not on master. (also do not rebase merge commits.) These commits are x1, x2, x3, x4, x6, x7, x8. x5 is a merge commit, so it's skipped. The m and n commits are on master and thus are not rebased. – David Sugar Nov 01 '19 at 14:59
  • @DavidSugar , If i my rebasing new_feature on master , then tip of master branch is `n6` and not `714da58` ? I never said rebase on `714da58` - which is anyways an intermediate commit . – Number945 Nov 01 '19 at 15:17
  • @BreakingBenjamin: as bk2204 said, the new base must be coming from the fork-point handling. In this case it appears to be nonsensical, so you might want to add `--no-fork-point` to your command line to prevent Git from using the fork-point method. – torek Nov 01 '19 at 15:46
  • @torek, unfortunately , the above repo is lost and when trying to run the git rebase command on similar examples, I am getting the right master commit to which the new_feature will and should rebase i.e. master tip. But one doubt here - Except `git rebase` and unless explicitly specified `--fork-point` flag , git rebase does not use fork-point method to calculate the better common ancestor. So, why did it was used in my case ? I just ran `git rebase -i master new_feature` ? – Number945 Nov 01 '19 at 17:22
  • When `git rebase` uses fork-point mode and when it does not is already pretty squirrelly (see [this question](https://stackoverflow.com/q/42616979/1256452) and related ones), *and*, the fork-point code uses the branch's *reflog*, which is unique to the set of manipulations that occurred in that one particular clone. I've never been a big fan of `--fork-point` and think that Git really should be using something more like Mercurial's "evolve" extension (but that would be very hard to bring to Git, and Evolve never became mainline Mercurial either). – torek Nov 01 '19 at 17:37
  • @torek , have a look at my answer. I found the answer for this behaviour :) – Number945 Nov 20 '19 at 20:43
  • @BreakingBenjamin: Yes, I saw the other question you asked, specifically about the comment line with the wrong hash ID in it. In fact, I answered it myself! I could delete my comment above, where I assumed the new base hash ID must be coming from the fork-point code (and it might actually be coming from there, who knows where the bug really is...) but since it isn't the actual base, it shouldn't be printed like that. – torek Nov 20 '19 at 21:48
0

Now, why I am getting 714da58 ? Should not it be da890d6 ?

Yes, it will be da890d6. There is bug in git for the display message error for rebase in certain scenarios.

Also, where is x5 (Git should rebase the commits that were merged in x5)?

When --rebase-merges option is not used with git rebase , any merge commit gets expanded (like here x5 which is merge commit, will be be dropped and n3,n4,n5,n6,m3 and m4 will be taken in its place) and git will put these commits into a single, linear branch (here above x4). But then observe, n3,n4,n5,n6,m3 and m4 are all shared by master and new_feature. Hence, new_feature..master will not select them which is what git rebase -i master new_feature will do.

Number945
  • 4,631
  • 8
  • 45
  • 83