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

Martin von Zweigbergk martinvonz at google.com
Fri May 29 21:24:13 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 fd058414aba23d7e3f95dbe7b9bcfada59602bb8
# Parent  a4acf019dd5b72e91a1b1321d80d298033be8111
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.

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 (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


More information about the Mercurial-devel mailing list