match: explicitly naming a subrepo implies always() for the submatcher
The files command supports naming directories to limit the output to children of
that directory, and it also supports -S to force recursion into a subrepo. But
previously, using -S and naming a subrepo caused nothing to be output. The
reason was narrowmatcher() strips the current subrepo path off of each file,
which would leave an empty list if only the subrepo was named.
When matching on workingctx, dirstate.matches() would see the submatcher is not
always(), so it returned the list of files in dmap for each file in the matcher-
namely, an empty list. If a directory in a subrepo was named, the output was as
expected, so this was inconsistent.
The 'not anypats()' check is enforced by an existing test around line 140:
$ hg remove -I 're:.*.txt' sub1
Without the check, this removed all of the files in the subrepo.
--- a/mercurial/match.py Sun May 17 01:06:10 2015 -0400
+++ b/mercurial/match.py Sun May 17 22:09:37 2015 -0400
@@ -260,6 +260,12 @@
self._files = [f[len(path) + 1:] for f in matcher._files
if f.startswith(path + "/")]
+
+ # If the parent repo had a path to this subrepo and no patterns are
+ # specified, this submatcher always matches.
+ if not self._always and not matcher._anypats:
+ self._always = util.any(f == path for f in matcher._files)
+
self._anypats = matcher._anypats
self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
self._fmap = set(self._files)
--- a/tests/test-subrepo-deep-nested-change.t Sun May 17 01:06:10 2015 -0400
+++ b/tests/test-subrepo-deep-nested-change.t Sun May 17 22:09:37 2015 -0400
@@ -216,6 +216,19 @@
sub1/sub2/missing: no such file in rev 78026e779ea6 (glob)
[1]
+ $ hg files -S -r '.^' sub1/
+ sub1/.hgsub (glob)
+ sub1/.hgsubstate (glob)
+ sub1/sub1 (glob)
+ sub1/sub2/folder/test.txt (glob)
+ sub1/sub2/sub2 (glob)
+ sub1/sub2/test.txt (glob)
+
+ $ hg files -S -r '.^' sub1/sub2
+ sub1/sub2/folder/test.txt (glob)
+ sub1/sub2/sub2 (glob)
+ sub1/sub2/test.txt (glob)
+
$ hg rollback -q
$ hg up -Cq