Patchwork [2,of,4] manifest: for diff(), only iterate over files, not flags

login
register
mail settings
Submitter Martin von Zweigbergk
Date Oct. 15, 2014, 7:02 a.m.
Message ID <ddddc4ac16f6eedd5ecf.1413356567@handduk2.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/6276/
State Accepted
Headers show

Comments

Martin von Zweigbergk - Oct. 15, 2014, 7:02 a.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@gmail.com>
# Date 1413352124 25200
#      Tue Oct 14 22:48:44 2014 -0700
# Node ID ddddc4ac16f6eedd5ecfab736f81e413e7163c70
# Parent  4d6a49d3f8d681b606dace0fec7ad6003490c650
manifest: for diff(), only iterate over files, not flags

From manifest.diff(), we return a dict from filename to pairs of pairs
of file nodeids and flags (values of the form ((n1,n2),(fl1,fl2))). To
create this dict, we currently generate one dict for files (with
(n1,n2) values) and one for flags (with (fl1,fl2) values) and then
join these dicts. Missing files are represented by None and missing
flags by '', but due to the dict joining, the inner pairs themselves
can also be None. The only caller, merge.manifestmerge(), then unpacks
these values while checking for None values.

By inlining the calls to dicthelpers and simplifying it to only
iterate over files (ignoring flags-only differences), we can simplify
life for our caller.

Patch

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -6,7 +6,7 @@ 
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import mdiff, parsers, error, revlog, util, dicthelpers
+import mdiff, parsers, error, revlog, util
 import array, struct
 
 class manifestdict(dict):
@@ -42,10 +42,26 @@ 
         '''Finds changes between the current manifest and m2. The result is
         returned as a dict with filename as key and values of the form
         ((n1,n2),(fl1,fl2)), where n1/n2 is the nodeid in the current/other
-        manifest and fl1/fl2 is the flag in the current/other manifest.'''
-        flagsdiff = dicthelpers.diff(self._flags, m2._flags, "")
-        fdiff = dicthelpers.diff(self, m2)
-        return dicthelpers.join(fdiff, flagsdiff)
+        manifest and fl1/fl2 is the flag in the current/other manifest. Where
+        the file does not exist, the nodeid will be None and the flags will be
+        the empty string.'''
+        diff = {}
+
+        for fn, n1 in self.iteritems():
+            fl1 = self._flags.get(fn, '')
+            n2 = m2.get(fn, None)
+            fl2 = m2._flags.get(fn, '')
+            if n2 is None:
+                fl2 = ''
+            if n1 != n2 or fl1 != fl2:
+                diff[fn] = ((n1, n2), (fl1, fl2))
+
+        for fn, n2 in m2.iteritems():
+            if fn not in self:
+                fl2 = m2._flags.get(fn, '')
+                diff[fn] = ((None, n2), ('', fl2))
+
+        return diff
 
     def text(self):
         fl = sorted(self)
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -424,22 +424,7 @@ 
     # Compare manifests
     diff = m1.diff(m2)
 
-    for f, (n12, fl12) in diff.iteritems():
-        if n12:
-            n1, n2 = n12
-        else: # file contents didn't change, but flags did
-            n1 = n2 = m1.get(f, None)
-            if n1 is None:
-                # Since n1 == n2, the file isn't present in m2 either. This
-                # means that the file was removed or deleted locally and
-                # removed remotely, but that residual entries remain in flags.
-                # This can happen in manifests generated by workingctx.
-                continue
-        if fl12:
-            fl1, fl2 = fl12
-        else: # flags didn't change, file contents did
-            fl1 = fl2 = m1.flags(f)
-
+    for f, ((n1, n2), (fl1, fl2)) in diff.iteritems():
         if partial and not partial(f):
             continue
         if n1 and n2: