fileset: narrow status computation by left-hand-side of 'and' node
authorYuya Nishihara <yuya@tcha.org>
Sun, 22 Jul 2018 19:48:50 +0900
changeset 38882 ff42ec7845e4
parent 38881 dec16c0cce50
child 38883 ee1ea96cf9c9
fileset: narrow status computation by left-hand-side of 'and' node Timing with warm disk cache: $ hg status --cwd mozilla-central 'set:path:build/ and unknown()' --time (orig) time: real 1.970 secs (user 1.560+0.000 sys 0.410+0.000) (new) time: real 0.330 secs (user 0.310+0.000 sys 0.020+0.000)
mercurial/fileset.py
--- a/mercurial/fileset.py	Sun Jul 22 19:43:57 2018 +0900
+++ b/mercurial/fileset.py	Sun Jul 22 19:48:50 2018 +0900
@@ -62,7 +62,7 @@
 
 def andmatch(mctx, x, y):
     xm = getmatch(mctx, x)
-    ym = getmatch(mctx, y)
+    ym = getmatch(mctx.narrowed(xm), y)
     return matchmod.intersectmatchers(xm, ym)
 
 def ormatch(mctx, *xs):
@@ -75,7 +75,7 @@
 
 def minusmatch(mctx, x, y):
     xm = getmatch(mctx, x)
-    ym = getmatch(mctx, y)
+    ym = getmatch(mctx.narrowed(xm), y)
     return matchmod.differencematcher(xm, ym)
 
 def listmatch(mctx, *xs):
@@ -460,19 +460,31 @@
         self._basectx = basectx
         self.ctx = ctx
         self._badfn = badfn
+        self._match = None
         self._status = None
 
+    def narrowed(self, match):
+        """Create matchctx for a sub-tree narrowed by the given matcher"""
+        mctx = matchctx(self._basectx, self.ctx, self._badfn)
+        mctx._match = match
+        # leave wider status which we don't have to care
+        mctx._status = self._status
+        return mctx
+
     def switch(self, basectx, ctx):
-        return matchctx(basectx, ctx, self._badfn)
+        mctx = matchctx(basectx, ctx, self._badfn)
+        mctx._match = self._match
+        return mctx
 
     def withstatus(self, keys):
         """Create matchctx which has precomputed status specified by the keys"""
         mctx = matchctx(self._basectx, self.ctx, self._badfn)
+        mctx._match = self._match
         mctx._buildstatus(keys)
         return mctx
 
     def _buildstatus(self, keys):
-        self._status = self._basectx.status(self.ctx,
+        self._status = self._basectx.status(self.ctx, self._match,
                                             listignored='ignored' in keys,
                                             listclean=True,
                                             listunknown='unknown' in keys)