>> b) The resulting path matches one of the parents but not one of >> the others. In such a case the merge should still be output if >> a 3-way read-tree would not have chosen this result by default. > I am not sure (b) is useful in general. Merging two branches > that fix the same issue but in different ways (think: 'maint' > and 'master' have different infrastructure and a fix initially > made on 'master' was backported to 'maint', and then later > 'maint' needed to be merged to 'master' to carry forward other > fixes) is a norm, and in such cases taking the version from the > merged-to branch is almost always what happens. > > Also it sounds to me by "if read-tree would not have chosen this > result by default" you mean this feature would not just need to > run merge-base but also recursive merge-base synthesis, and also > recreate the structural merge (aka "rename detection") there as > well. Even if (b) is useful, it sounds like a very expensive > option, and the current merge-recursive code is structured in > such a way to be easily reused for this purpose. These seem like roundabout ways of expressing the requirement. The desired rule is "no silent changes in the simplified history". E.g. if the revision history of a particular file is: +-C-+ / \ A---B B---D \ / +-B-+ Then the normal code will notice that there are no changes on the lower branch, prune the merge entirely, and simplify to A---B---C---D. This is, however, misleading; the true history is A---B---C---B---D. A merge must be shown unless it matches a *non-eliminated* ancestor. The point is that this isn't expressed in terms of what merge-base would do, but in terms of what the path limiter is in the process of doing. Now, I haven't dived into the Deep Magic of revision.c to figure out where to put this into the code, unfortunately. Another way to say it is that the desired simplified history is achieved when you have exhausted the following two rules: - You may delete any revision which has only one ancestor and is identical (after path-limiting) to that ancestor. (Descendants are implicitly linked to that ancestor.) - You may delete any ancestor link A---B if there is an alternative directed path between A and B. (Fast-forward rule.) Given unlabeled ancestor links, there is a unique fixed point. The current code is willing to delete a revision that is identical to *any* ancestor, even deleted ones. - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html