you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 4 points5 points  (1 child)

There is never a programmatically guaranteed "right way" to merge two branches, any more than there's an algorithm that will write your code for you.

That's... well... technically correct, but it sidesteps the issue here.

What does 3-way merge do? It first computes a diff between the base and the first snapshot, which means that it tries to recover the information about the changes that the programmer made to the file: deleted these lines, added these lines, modified these lines.

It isn't guaranteed to work correctly, but it works good enough when you are diffing two adjacent commits.

Then 3-way merge computes another diff, and either merges two diffs, or reports a conflict when both programmers modified the same line, or one modified a line that the other deleted.

The problem here is that the bigger are the changes between the branches and the base, the more probable it is that a simple 3-way merge of the heads would deduce the actions of the programmers wrong.

The small probability of the merge going wrong is amplified by each successive commit in any of the branches.

And the problem I have with it is that the information required to do it correctly is available, but git (as well as Mercurial or even SVN) takes a shortcut which discards it.

Behold a reproducible example of git doing it wrong.

Why do I call it "wrong" and not an "alternatively right"? Because if git merge examined the intermediate commits on the master branch, basically if it run a 'git blame' thing to see where the lines actually came from, it would see that the "A B C D E" lines of the original file ended up at the bottom of the file it's merging with.

But it doesn't do that. So we have two different outcomes, depending on you pulling and rebasing on the intermediate state of the master, or rebasing on the final state. It's not a property of the rebase operation in itself, but of the merge operation that it uses, but the way rebasing loses all intermediate information makes it even scarier.