merge: clarify the findcopies code
authorMatt Mackall <mpm@selenic.com>
Thu, 03 May 2007 17:24:43 -0500
changeset 4396 c04c96504a12
parent 4359 80d3f6f0d8e5
child 4397 9fe267f77f56
merge: clarify the findcopies code
mercurial/merge.py
--- a/mercurial/merge.py	Wed Apr 25 13:35:18 2007 -0500
+++ b/mercurial/merge.py	Thu May 03 17:24:43 2007 -0500
@@ -133,14 +133,15 @@
     def checkcopies(c, man):
         '''check possible copies for filectx c'''
         for of in findold(c):
-            if of not in man:
+            if of not in man: # original file not in other manifest?
                 continue
             c2 = ctx(of, man[of])
             ca = c.ancestor(c2)
-            if not ca: # unrelated
+            if not ca: # unrelated?
                 continue
+            # named changed on only one side?
             if ca.path() == c.path() or ca.path() == c2.path():
-                fullcopy[c.path()] = of
+                fullcopy[c.path()] = of # remember for dir rename detection
                 if c == ca and c2 == ca: # no merge needed, ignore copy
                     continue
                 copy[c.path()] = of
@@ -179,16 +180,25 @@
     invalid = {}
     dirmove = {}
 
+    # examine each file copy for a potential directory move, which is
+    # when all the files in a directory are moved to a new directory
     for dst, src in fullcopy.items():
         dsrc, ddst = os.path.dirname(src), os.path.dirname(dst)
         if dsrc in invalid:
+            # already seen to be uninteresting
             continue
-        elif (dsrc in d1 and ddst in d1) or (dsrc in d2 and ddst in d2):
+        elif dsrc in d1 and ddst in d1:
+            # directory wasn't entirely moved locally
+            invalid[dsrc] = True
+        elif dsrc in d2 and ddst in d2:
+            # directory wasn't entirely moved remotely
             invalid[dsrc] = True
         elif dsrc in dirmove and dirmove[dsrc] != ddst:
+            # files from the same directory moved to two different places
             invalid[dsrc] = True
             del dirmove[dsrc]
         else:
+            # looks good so far
             dirmove[dsrc + "/"] = ddst + "/"
 
     del d1, d2, invalid
@@ -196,11 +206,12 @@
     if not dirmove:
         return copy
 
-    # check unaccounted nonoverlapping files
+    # check unaccounted nonoverlapping files against directory moves
     for f in u1 + u2:
         if f not in fullcopy:
             for d in dirmove:
                 if f.startswith(d):
+                    # new file added in a directory that was moved, move it
                     copy[f] = dirmove[d] + f[len(d):]
                     break