diff options
-rw-r--r-- | git/index/fun.py | 138 |
1 files changed, 71 insertions, 67 deletions
diff --git a/git/index/fun.py b/git/index/fun.py index f1b05f16..dbe25276 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -13,6 +13,7 @@ from stat import ( S_IFREG, S_IXUSR, ) + import subprocess from git.cmd import PROC_CREATIONFLAGS, handle_process_output @@ -339,76 +340,79 @@ def aggressive_tree_merge(odb, tree_shas: Sequence[bytes]) -> List[BaseIndexEntr raise ValueError("Cannot handle %i trees at once" % len(tree_shas)) # three trees - for entryo in traverse_trees_recursive(odb, tree_shas, ''): - assert is_three_entry_list(entryo), f"{type(entryo)=} and {len(entryo)=}" # type:ignore - base, ours, theirs = entryo - if base is not None: - # base version exists - if ours is not None: - # ours exists - if theirs is not None: - # it exists in all branches, if it was changed in both - # its a conflict, otherwise we take the changed version - # This should be the most common branch, so it comes first - if(base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or \ - (base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]): - # changed by both - out.append(_tree_entry_to_baseindexentry(base, 1)) - out.append(_tree_entry_to_baseindexentry(ours, 2)) - out.append(_tree_entry_to_baseindexentry(theirs, 3)) - elif base[0] != ours[0] or base[1] != ours[1]: - # only we changed it - out.append(_tree_entry_to_baseindexentry(ours, 0)) - else: - # either nobody changed it, or they did. In either - # case, use theirs - out.append(_tree_entry_to_baseindexentry(theirs, 0)) - # END handle modification + entries = traverse_trees_recursive(odb, tree_shas, '') + base = entries[0] + ours = entries[1] + theirs = entries[2] + assert is_three_entry_list(entries), f"{type(entries)=} and {len(entries)=}" # type:ignore + + if base is not None: + # base version exists + if ours is not None: + # ours exists + if theirs is not None: + # it exists in all branches, if it was changed in both + # its a conflict, otherwise we take the changed version + # This should be the most common branch, so it comes first + if(base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or \ + (base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]): + # changed by both + out.append(_tree_entry_to_baseindexentry(base, 1)) + out.append(_tree_entry_to_baseindexentry(ours, 2)) + out.append(_tree_entry_to_baseindexentry(theirs, 3)) + elif base[0] != ours[0] or base[1] != ours[1]: + # only we changed it + out.append(_tree_entry_to_baseindexentry(ours, 0)) else: - - if ours[0] != base[0] or ours[1] != base[1]: - # they deleted it, we changed it, conflict - out.append(_tree_entry_to_baseindexentry(base, 1)) - out.append(_tree_entry_to_baseindexentry(ours, 2)) - # else: - # we didn't change it, ignore - # pass - # END handle our change - # END handle theirs + # either nobody changed it, or they did. In either + # case, use theirs + out.append(_tree_entry_to_baseindexentry(theirs, 0)) + # END handle modification else: - if theirs is None: - # deleted in both, its fine - its out - pass - else: - if theirs[0] != base[0] or theirs[1] != base[1]: - # deleted in ours, changed theirs, conflict - out.append(_tree_entry_to_baseindexentry(base, 1)) - out.append(_tree_entry_to_baseindexentry(theirs, 3)) - # END theirs changed - # else: - # theirs didn't change - # pass - # END handle theirs - # END handle ours - else: - # all three can't be None - if ours is None and theirs is not None: - # added in their branch - out.append(_tree_entry_to_baseindexentry(theirs, 0)) - elif theirs is None and ours is not None: - # added in our branch - out.append(_tree_entry_to_baseindexentry(ours, 0)) - elif ours is not None and theirs is not None: - # both have it, except for the base, see whether it changed - if ours[0] != theirs[0] or ours[1] != theirs[1]: + + if ours[0] != base[0] or ours[1] != base[1]: + # they deleted it, we changed it, conflict + out.append(_tree_entry_to_baseindexentry(base, 1)) out.append(_tree_entry_to_baseindexentry(ours, 2)) + # else: + # we didn't change it, ignore + # pass + # END handle our change + # END handle theirs + else: + if theirs is None: + # deleted in both, its fine - its out + pass + else: + if theirs[0] != base[0] or theirs[1] != base[1]: + # deleted in ours, changed theirs, conflict + out.append(_tree_entry_to_baseindexentry(base, 1)) out.append(_tree_entry_to_baseindexentry(theirs, 3)) - else: - # it was added the same in both - out.append(_tree_entry_to_baseindexentry(ours, 0)) - # END handle two items - # END handle heads - # END handle base exists - # END for each entries tuple + # END theirs changed + # else: + # theirs didn't change + # pass + # END handle theirs + # END handle ours + else: + # all three can't be None + if ours is None and theirs is not None: + # added in their branch + out.append(_tree_entry_to_baseindexentry(theirs, 0)) + elif theirs is None and ours is not None: + # added in our branch + out.append(_tree_entry_to_baseindexentry(ours, 0)) + elif ours is not None and theirs is not None: + # both have it, except for the base, see whether it changed + if ours[0] != theirs[0] or ours[1] != theirs[1]: + out.append(_tree_entry_to_baseindexentry(ours, 2)) + out.append(_tree_entry_to_baseindexentry(theirs, 3)) + else: + # it was added the same in both + out.append(_tree_entry_to_baseindexentry(ours, 0)) + # END handle two items + # END handle heads + # END handle base exists +# END for each entries tuple return out |