Prerequisite: http://thread.gmane.org/gmane.comp.version-control.monotone.devel/4297
A user can make 2 types of merge decisions: (1): One parent is better than the other (represented by *) (2): Both parents are wrong (represented by ^) Since there are 2 types of merge decisions, it would be bad to treat all merge decisions the same. Also, in the case of merge(a, a) = a, it is possible for there to be multiple least decision ancestors. ===== Define: ^(A) is the set of ancestors of A that it gets its value from (found by setting N=A and iterating N = *(N) until there is no change) *(A) is the set of least ancestors of A in which the user made a decision note that erase_ancestors(^(A)) = ^(A), and erase_ancestors(*(A)) = *(A) ===== & is intersection, | is union *(A) has the same properties as before, except that it is not a single ancestor, but a set. This set can acquire more than one member only in the case of Aa Ba \ / Ca , where *(A) and *(B) are different; *(C) will be erase_ancestors(*(A) | *(B)) The ancestory corollary becomes: any ancestor C of A with value(C) != value(A) will be an ancestor of at least one member of *(A) When merging A and B: # if one side knows of _all_ places that the other side was chosen, it wins (1) set X = erase_ancestors(*(A) | *(B)) if X & *(B) = {}, A wins if X & *(A) = {}, B wins else, X contains members of both *(A) and *(B) # if one side knows of _all_ places that the other side originated, it wins (2) set Y = erase_ancestors(*(A) | ^(B)) set Z = erase_ancestors(*(B) | ^(A)) if Y & ^(B) = {} and Z & ^(A) = {}, conflict if Y & ^(B) = {}, A wins if Z & ^(A) = {}, B wins # if one side knows of _any_ places that the other side originated, it wins (3) if Y & ^(B) != ^(B) and Z & ^(A) != ^(A), conflict if Y & ^(B) != ^(B), A wins if Z & ^(A) != ^(A), B wins # else, nobody knows anything (4) conflict (3) is convergence, and can be safely left out if unwanted ==== "Funky cases" Coincidental clean does not exist; a mark is only needed when there is user intervention. | a / \ b b \ / \ b c and the example after it will resolve cleanly iff (3) is included. | a / \ b* c* / \ / \ c* X b* \ / \ / c b will be a conflict. a / \ b* c* \ / \ c* d* This ("the other funky case") is handled by (2), and resolves cleanly. Tim _______________________________________________ Monotone-devel mailing list Monotone-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/monotone-devel