match: add visitchildrenset complement to visitdir
`visitdir(d)` lets a caller query whether the directory is part of the matcher.
It can receive a response of 'all' (yes, and all children, you can stop calling
visitdir now), False (no, and no children either), or True (yes, either
something in this directory or a child is part of the matcher).
`visitchildrenset(d)` augments that by instead of returning True, it returns a
list of items to actually investigate. With this, code can be modified from:
for f in self.all_items:
if match.visitdir(self.dir + '/' + f):
<do stuff>
to be:
for f in self.all_items.intersect(match.visitchildrenset(self.dir)):
<do stuff>
use of this function can provide significant performance improvements,
especially when using narrow (so that the matcher is much smaller than the stuff
we see on disk) and/or treemanifests (so that we can avoid loading manifests for
trees that aren't part of the matcher).
Differential Revision: https://phab.mercurial-scm.org/D4130
#require test-repo execbit
$ . "$TESTDIR/helpers-testrepo.sh"
$ cd "`dirname "$TESTDIR"`"
look for python scripts without the execute bit
$ testrepohg files 'set:**.py and not exec() and grep(r"^#!.*?python")'
[1]
look for python scripts with execute bit but not shebang
$ testrepohg files 'set:**.py and exec() and not grep(r"^#!.*?python")'
[1]
look for shell scripts with execute bit but not shebang
$ testrepohg files 'set:**.sh and exec() and not grep(r"^#!.*(ba)?sh")'
[1]
look for non scripts with no shebang
$ testrepohg files 'set:exec() and not **.sh and not **.py and not grep(r"^#!")'
[1]