Search code examples
gitrebasegit-merge-conflict

git rebase: why do I get conflicts rebasing on top of the same state as the common ancestor?


I would like to better understand something I am observing with Git, using git --version 2.39.2.

In a repo, I have two long-lived branches, the default master and a new one, branched from master several months ago. In the last months, there was some maintenance work done in master, with occasional cherry-picking into new. On the other hand, there was a lot of work on new, with many PRs merged into it and more than 600 commits on top of the branching point.

I now want to rebase new on top of master, to then merge new into master. When rebasing, I had a few minor conflicts, which however risked to spoil the history, as for instance they would make it harder to track which dependency versions were used exactly back in time. I thus decided to do the following:

  1. I added (locally) a commit to master, bringing its state back to the common ancestor of the two branches. I used this: https://stackoverflow.com/a/51906191/6760680
  2. I then rebased new on top of this "edited" master, which also implies that it's rebased on top of the remote master, so I can use this rebased version to merge.

Now, the question is: why did I still get some (small) conflicts, when doing this procedure?

I was rebasing on top of a state that was identical to the common ancestor of the two branches, so I expected no conflict at all. I am slightly worried that the history might be messed up due to this (hard to check, as it's many commits, as I said), even if the final state of the branch is the expected one. Note that I rebased with the --rebase-merges option, because I want to keep the merge commits, not sure if that can be related. Can somebody with deeper Git insights illuminate me?


Solution

  • ok..... I think your problem is the rebase itself, at least current git's implementation for rebasing merges.... even if you use --rebase-merges and the trees involved are exactly one like the other to start with, if there is a conflict with a merge, git does not care for the trees been the same and will let you do the conflict resolution instead of using the tree of the original merge commit. We will someday tackle this in upstream but for the time being, I can offer this script:

    https://github.com/eantoranz/git/blob/replay/contrib/replay

    I haven't used it in a while so take it with a grain of salt... the good thing is that it doesn't move anything around.... it will print a commit ID after it has run. That commit has the rebased history, feel free to put a branch there when you are sure that branch history is what you want to have.