manifest: add match argument to diff and filesnotin
authorDurham Goode <durham@fb.com>
Tue, 07 Mar 2017 09:56:11 -0800
changeset 31265 959ebff3505a
parent 31264 2140e12d3258
child 31266 5a909a8098a1
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.
mercurial/manifest.py
tests/test-manifest.py
--- a/mercurial/manifest.py	Thu Mar 09 00:07:13 2017 +0900
+++ b/mercurial/manifest.py	Tue Mar 07 09:56:11 2017 -0800
@@ -445,8 +445,12 @@
     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 @@
         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 @@
         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 @@
             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 @@
             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 @@
         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):
--- a/tests/test-manifest.py	Thu Mar 09 00:07:13 2017 +0900
+++ b/tests/test-manifest.py	Tue Mar 07 09:56:11 2017 -0800
@@ -320,7 +320,7 @@
             '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(