treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?'
authorMartin von Zweigbergk <martinvonz@google.com>
Wed, 27 May 2015 10:44:04 -0700
changeset 25362 20ad936ac5d2
parent 25361 1635579f9baf
child 25363 3ff4b07412ad
treemanifest: visit directory 'foo' when given e.g. '-X foo/ba?' For globs like 'foo/ba?', match._roots() will return 'foo'. Since visitdir(), excludes directories in the excluded roots, it would skip the entire foo directory. This is incorrect, since 'foo/ba?' doesn't mean that everything in foo/ should be exluded. Note that visitdir() is called only from the treemanifest class, so this only affects tree manifests. Fix by adding roots to the set of excluded roots only 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.
mercurial/match.py
tests/test-treemanifest.t
--- a/mercurial/match.py	Fri May 29 14:24:50 2015 -0700
+++ b/mercurial/match.py	Wed May 27 10:44:04 2015 -0700
@@ -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):
--- a/tests/test-treemanifest.t	Fri May 29 14:24:50 2015 -0700
+++ b/tests/test-treemanifest.t	Wed May 27 10:44:04 2015 -0700
@@ -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 (glob)
   $ 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 (glob)
   b/bar/orange/fly/gnat.py (glob)
   b/bar/orange/fly/housefly.txt (glob)
@@ -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 (glob)
   b/bar/orange/fly/housefly.txt (glob)
   $ 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 (glob)
   $ mv oldmf .hg/store/meta/a
   $ mv oldmf2 .hg/store/meta/b/foo