[PATCH 09 of 11] mergecopies: process rotated-DAG divergences from _checkcopies (issue4028)

Gábor Stefanik gabor.stefanik at nng.com
Wed Oct 5 08:05:02 EDT 2016


# HG changeset patch
# User Gábor Stefanik <gabor.stefanik at nng.com>
# Date 1475578314 -7200
#      Tue Oct 04 12:51:54 2016 +0200
# Node ID bbc77d871f41a85db381b57acfe6dc550bb40506
# Parent  8ae0f32d74ea2fe2a4b47b9b36624459b3c1531f
mergecopies: process rotated-DAG divergences from _checkcopies (issue4028)

diff -r 8ae0f32d74ea -r bbc77d871f41 mercurial/copies.py
--- a/mercurial/copies.py	Tue Oct 04 15:38:43 2016 +0200
+++ b/mercurial/copies.py	Tue Oct 04 12:51:54 2016 +0200
@@ -321,6 +321,7 @@
     if repo.ui.configbool('experimental', 'disablecopytrace'):
         return {}, {}, {}, {}
 
+    dirtyc1 = False # dummy bool for later use
     limit = _findlimit(repo, c1.rev(), c2.rev())
     if limit is None:
         # no common ancestor, no copies
@@ -357,6 +358,27 @@
     movewithdir = dict(movewithdir1.items() + movewithdir2.items())
     fullcopy = dict(fullcopy1.items() + fullcopy2.items())
 
+    # combine partial copy paths discovered in the previous step
+    def _combinecopies(copyfrom, copyto, diverge):
+        remainder = {}
+        for f in copyfrom:
+            if f in copyto:
+                copy[copyto[f]] = copyfrom[f]
+                del copyto[f]
+        for f in incompletediverge:
+            assert f not in diverge
+            ic = incompletediverge[f]
+            if ic[0] in copyto:
+                diverge[f] = [copyto[ic[0]], ic[1]]
+            else:
+                remainder[f] = ic
+        return remainder
+
+    if dirtyc1:
+        _combinecopies(incomplete2, incomplete1, diverge)
+    else:
+        _combinecopies(incomplete1, incomplete2, diverge)
+
     renamedelete = {}
     renamedeleteset = set()
     divergeset = set()
@@ -383,6 +405,18 @@
                      _fullcopy, incomplete1, incompletediverge)
         _checkcopies(c2, f, m2, m1, ca, ca, False, limit, bothdiverge, _copy,
                      _fullcopy, incomplete2, incompletediverge)
+    if dirtyc1:
+        assert incomplete2 == {}
+        remainder = _combinecopies({}, incomplete1, bothdiverge)
+    else:
+        assert incomplete1 == {}
+        remainder = _combinecopies({}, incomplete2, bothdiverge)
+    for f in remainder:
+        assert f not in bothdiverge
+        ic = remainder[f]
+        if ic[0] in (m1 if dirtyc1 else m2):
+            # backed-out rename on one side, but watch out for deleted files
+            bothdiverge[f] = ic
     for of, fl in bothdiverge.items():
         if len(fl) == 2 and fl[0] == fl[1]:
             copy[fl[0]] = of # not actually divergent, just matching renames


More information about the Mercurial-devel mailing list