sparse: make use of matchers for faster path listing

Summary:
The current code iterates over all files in the manifest, filtering against a prefix.

But a manifest supports using a matcher directly, and efficient implementations like the treemanifest will prune the tree to a much smaller subset rapidly based on the path in a matcher. Switching to using a matcher dramatically improves --cwd-list performance in fbsource, when treemanifests are available.

Reviewed By: quark-zju

Differential Revision: D7056650

fbshipit-source-id: 2bf62ea93680323a49c9282266118805881d7b02
This commit is contained in:
Martijn Pieters 2018-03-06 04:23:56 -08:00 committed by Saurabh Singh
parent cc75e9e988
commit 3b4b3d8cbb
2 changed files with 62 additions and 6 deletions

View File

@ -1214,18 +1214,22 @@ def _cwdlist(repo):
_("the current working directory should begin "
"with the root %s") % root)
matcher = matchmod.match(
repo.root, repo.getcwd(),
patterns=['path:' + cwd])
files = mf.matches(matcher)
sparsematch = repo.sparsematch(ctx.rev())
checkedoutentries = set()
allentries = set()
cwdlength = len(cwd)
for filepath in mf:
if filepath.startswith(cwd):
entryname = filepath[cwdlength:].partition(pycompat.ossep)[0]
for filepath in files:
entryname = filepath[cwdlength:].partition(pycompat.ossep)[0]
allentries.add(entryname)
if sparsematch(filepath):
checkedoutentries.add(entryname)
allentries.add(entryname)
if sparsematch(filepath):
checkedoutentries.add(entryname)
ui = repo.ui
for entry in sorted(allentries):

View File

@ -0,0 +1,52 @@
test interaction between sparse and treemanifest (sparse file listing)
$ cat >> $HGRCPATH <<EOF
> [extensions]
> sparse=$TESTDIR/../hgext/fbsparse.py
> treemanifest=
> [treemanifest]
> treeonly = True
> [remotefilelog]
> reponame = master
> cachepath = $PWD/hgcache
> EOF
Setup the repository
$ hg init myrepo
$ cd myrepo
$ touch show
$ touch hide
$ mkdir -p subdir/foo/spam subdir/bar/ham hiddensub/foo hiddensub/bar
$ touch subdir/foo/spam/show
$ touch subdir/bar/ham/hide
$ touch hiddensub/foo/spam
$ touch hiddensub/bar/ham
$ hg add .
adding hiddensub/bar/ham
adding hiddensub/foo/spam
adding hide
adding show
adding subdir/bar/ham/hide
adding subdir/foo/spam/show
$ hg commit -m 'Init'
$ hg sparse --include show
$ hg sparse --exclude hide
$ hg sparse --include subdir
$ hg sparse --exclude subdir/foo
Test --cwd-list
$ hg sparse --cwd-list
- hiddensub
- hide
show
subdir
$ cd subdir
$ hg sparse --cwd-list
bar
- foo
$ hg sparse --include foo
$ hg sparse --cwd-list
bar
- foo