Zooko provides a nice example of the problems with most distributed version control systems merge algorithms. He gives an example of a merge situation that most version control systems, including git, get wrong, but that darcs, Codeville, SCCS, and perhaps BitKeeper get correct.
Still there are some people who argue either that method git does is correct, or that there is no right or wrong way to merge and the results are just different. Rather than argue that git’s method is right or wrong, I want to argue that git method (and other’s like git) is inconsistent.
The problem with git’s merging is that it doesn’t satisfy the “merge associativity law” which states that merging change A into a branch followed by merging change B into the branch gives the same results as merging both changes in together in one merge.
The source of Zooko’s bad merge stems from a failure to follow the merge associativity law. I have modified a shell script written by Simon Marlow that illustrates, using git, how merging two patches separately can give different results than merging two patches together.
In the first case, merging both patches separately, the history looks as follows.
and results in the file:
A B C D E # # # A B changed C D E
In the second case, merging both patches together in one merge, the history looks as follows.
and results in the file:
A B changed C D E # # # A B C D E
Roughly speaking, the merge associativity law states that having extra "rungs" in the history "ladder" between two branches ought not to make a difference in the final result.
There are still some people who still think nothing is wrong with git; that it is okay for the result of a merge to depend on how things are merged rather than on only what is merged; that is it okay for two git repositories that pull the same patches to have different contents depending on how they pulled those patches. I don’t know what to say to those people. Such a view seems like insanity to me.