[PATCH 1 of 6] manifest: add match argument to diff and filesnotin

Durham Goode durham at fb.com
Fri Mar 3 19:34:16 UTC 2017


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1488519802 28800
#      Thu Mar 02 21:43:22 2017 -0800
# Node ID e2ec7a1c68da7209233489a5c05efc5728463632
# Parent  b4cd912d7704cd976e1bee3a3c927e0e578ec88f
manifest: add match argument to diff and filesnotin

As part of removing manifest.matches (since it is O(manifest)), let's start by
adding match arguments to diff and filesnotin. As we'll see in later patches,
these are the only flows that actually use matchers, so by moving the matching
into the actual functions, other manifest implementations can make more efficient
algorithsm.

For instance, this will allow treemanifest diff's to only iterate over the files
that are different AND meet the match criteria.

No consumers are changed in this patches, but the code is fairly easy to verify
visually. Future patches will convert consumers to use it.

One test was affected because it did not use the kwargs version of the clean
parameter.

diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -445,8 +445,12 @@ class manifestdict(object):
     def keys(self):
         return list(self.iterkeys())
 
-    def filesnotin(self, m2):
+    def filesnotin(self, m2, match=None):
         '''Set of files in this manifest that are not in the other'''
+        if match:
+            m1 = self.matches(match)
+            m2 = m2.matches(match)
+            return m1.filesnotin(m2)
         diff = self.diff(m2)
         files = set(filepath
                     for filepath, hashflags in diff.iteritems()
@@ -523,7 +527,7 @@ class manifestdict(object):
         m._lm = self._lm.filtercopy(match)
         return m
 
-    def diff(self, m2, clean=False):
+    def diff(self, m2, match=None, clean=False):
         '''Finds changes between the current manifest and m2.
 
         Args:
@@ -538,6 +542,10 @@ class manifestdict(object):
         the nodeid will be None and the flags will be the empty
         string.
         '''
+        if match:
+            m1 = self.matches(match)
+            m2 = m2.matches(match)
+            return m1.diff(m2, clean=clean)
         return self._lm.diff(m2._lm, clean)
 
     def setflag(self, key, flag):
@@ -906,8 +914,13 @@ class treemanifest(object):
             copy._copyfunc = self._copyfunc
         return copy
 
-    def filesnotin(self, m2):
+    def filesnotin(self, m2, match=None):
         '''Set of files in this manifest that are not in the other'''
+        if match:
+            m1 = self.matches(match)
+            m2 = m2.matches(match)
+            return m1.filesnotin(m2)
+
         files = set()
         def _filesnotin(t1, t2):
             if t1._node == t2._node and not t1._dirty and not t2._dirty:
@@ -1025,7 +1038,7 @@ class treemanifest(object):
             ret._dirty = True
         return ret
 
-    def diff(self, m2, clean=False):
+    def diff(self, m2, match=None, clean=False):
         '''Finds changes between the current manifest and m2.
 
         Args:
@@ -1040,6 +1053,10 @@ class treemanifest(object):
         the nodeid will be None and the flags will be the empty
         string.
         '''
+        if match:
+            m1 = self.matches(match)
+            m2 = m2.matches(match)
+            return m1.diff(m2, clean=clean)
         result = {}
         emptytree = treemanifest()
         def _diff(t1, t2):
diff --git a/tests/test-manifest.py b/tests/test-manifest.py
--- a/tests/test-manifest.py
+++ b/tests/test-manifest.py
@@ -320,7 +320,7 @@ class basemanifesttests(object):
             'bar/baz/qux.py': None,
             'foo': (MISSING, (BIN_HASH_1, '')),
             }
-        self.assertEqual(want, pruned.diff(short, True))
+        self.assertEqual(want, pruned.diff(short, clean=True))
 
     def testReversedLines(self):
         backwards = ''.join(


More information about the Mercurial-devel mailing list