[PATCH] match: visit directory 'foo' when given e.g. '-X foo/ba?'

Martin von Zweigbergk martinvonz at google.com
Wed May 27 22:16:35 UTC 2015


# HG changeset patch
# User Martin von Zweigbergk <martinvonz at google.com>
# Date 1432748644 25200
#      Wed May 27 10:44:04 2015 -0700
# Node ID 39829cc793a5df9d598b81eb2c62ef50da50f16a
# Parent  6ac860f700b5cfeda232d5305963047696b869ca
match: visit directory 'foo' when given e.g. '-X foo/ba?'

For globs like 'foo/ba?', _roots() will return 'foo'. Since visitdir
excludes directories in the excluded roots, it would skip the entire
foo directory, which is incorrect, since 'foo/ba?' doesn't mean that
everything in foo/ should be exluded. Fix by only adding roots to the
set of excluded roots if there are no excluded patterns.

Since 'glob' is the default pattern type for globs, we also need to
update some -X patterns in the tests to be of 'path' type to take
advantage of the visitdir tricks. For consistency, also update the -I
patterns.

It seems a little unfortunate that 'foo' in 'hg files -X foo' is
considered a pattern because of the implied 'glob' type, but improving
that is left for another day.

diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -129,8 +129,9 @@
             kindpats = self._normalize(exclude, 'glob', root, cwd, auditor)
             self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
                                               listsubrepos, root)
-            self._excluderoots.update(_roots(kindpats))
-            self._excluderoots.discard('.')
+            if not _anypats(kindpats):
+                self._excluderoots.update(_roots(kindpats))
+                self._excluderoots.discard('.')
             matchfns.append(lambda f: not em(f))
         if exact:
             if isinstance(patterns, list):
diff --git a/tests/test-treemanifest.t b/tests/test-treemanifest.t
--- a/tests/test-treemanifest.t
+++ b/tests/test-treemanifest.t
@@ -322,6 +322,13 @@
   c.txt
   d.py
 
+Excludes with a glob should not exclude everything from the glob's root
+
+  $ hg files -r . -X 'b/fo?' b
+  b/bar/fruits.txt
+  b/bar/orange/fly/gnat.py
+  b/bar/orange/fly/housefly.txt
+
 Test files for a subdirectory.
 
   $ mv .hg/store/meta/a oldmf
@@ -337,7 +344,7 @@
   $ mv .hg/store/meta/a oldmf
   $ mv .hg/store/meta/b/bar/orange/fly oldmf2
   $ mv .hg/store/meta/b/foo/apple/bees oldmf3
-  $ hg files -r . -I b/bar -X b/bar/orange/fly -I b/foo -X b/foo/apple/bees
+  $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
   b/bar/fruits.txt
   $ mv oldmf .hg/store/meta/a
   $ mv oldmf2 .hg/store/meta/b/bar/orange/fly
@@ -347,7 +354,7 @@
 
   $ mv .hg/store/meta/a oldmf
   $ mv .hg/store/meta/b/foo oldmf2
-  $ hg files -r . -X b/foo b
+  $ hg files -r . -X path:b/foo b
   b/bar/fruits.txt
   b/bar/orange/fly/gnat.py
   b/bar/orange/fly/housefly.txt
@@ -359,7 +366,7 @@
 
   $ mv .hg/store/meta/a oldmf
   $ mv .hg/store/meta/b/foo oldmf2
-  $ hg files -r . -I b/bar/orange -I a b
+  $ hg files -r . -I path:b/bar/orange -I path:a b
   b/bar/orange/fly/gnat.py
   b/bar/orange/fly/housefly.txt
   $ mv oldmf .hg/store/meta/a
@@ -371,7 +378,7 @@
   $ mv .hg/store/meta/a oldmf
   $ mv .hg/store/meta/b/foo oldmf2
   $ mv .hg/store/meta/b/bar/orange oldmf3
-  $ hg files -r . glob:**.txt -I b/bar -X b/bar/orange
+  $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
   b/bar/fruits.txt
   $ mv oldmf .hg/store/meta/a
   $ mv oldmf2 .hg/store/meta/b/foo


More information about the Mercurial-devel mailing list