Patchwork [5,of,5] match: fix visitdir for roots of includes

login
register
mail settings
Submitter via Mercurial-devel
Date May 24, 2017, 12:04 a.m.
Message ID <c52a8f80fddfc1d3f8fe.1495584277@martinvonz.svl.corp.google.com>
Download mbox | patch
Permalink /patch/20875/
State Accepted
Headers show

Comments

via Mercurial-devel - May 24, 2017, 12:04 a.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1494970281 25200
#      Tue May 16 14:31:21 2017 -0700
# Node ID c52a8f80fddfc1d3f8fee944e885d1ffe72ea762
# Parent  af9dcab6479262b7ac8a570ac8607534079e6f84
match: fix visitdir for roots of includes

I'm hoping to rewrite the matcher so excludes are handled by
composition of one matcher with another matcher where the second
matcher has only includes. For that to work, we need to make
visitdir() to return 'all' for directory 'foo' for a '-I foo' matcher.

Patch

diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -306,6 +306,7 @@ 
             exclude = []
 
         self._anypats = bool(include or exclude)
+        self._anyincludepats = False
         self._always = False
         self._pathrestricted = bool(include or exclude or patterns)
         self.patternspat = None
@@ -323,6 +324,7 @@ 
             kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
             self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
                                               listsubrepos, root)
+            self._anyincludepats = _anypats(kindpats)
             roots, dirs = _rootsanddirs(kindpats)
             self._includeroots.update(roots)
             self._includedirs.update(dirs)
@@ -380,13 +382,18 @@ 
             return 'all'
         if dir in self._excluderoots:
             return False
-        if ((self._includeroots or self._includedirs) and
-            '.' not in self._includeroots and
-            dir not in self._includeroots and
-            dir not in self._includedirs and
-            not any(parent in self._includeroots
-                    for parent in util.finddirs(dir))):
-            return False
+        if self._includeroots or self._includedirs:
+            if (not self._anyincludepats and
+                not self._excluderoots and
+                dir in self._includeroots):
+                # The condition above is essentially self.prefix() for includes
+                return 'all'
+            if ('.' not in self._includeroots and
+                dir not in self._includeroots and
+                dir not in self._includedirs and
+                not any(parent in self._includeroots
+                        for parent in util.finddirs(dir))):
+                return False
         return (not self._fileset or
                 '.' in self._fileset or
                 dir in self._fileset or