Skip to content
Snippets Groups Projects
Commit 8545bd381504 authored by Drew Gottlieb's avatar Drew Gottlieb
Browse files

match: have visitdir() consider includes and excludes

match.visitdir() used to only look at the match's primary pattern roots to
decide if a treemanifest traverser should descend into a particular directory.
This change logically makes visitdir also consider the match's include and
exclude pattern roots (if applicable) to make this decision.

This is especially important for situations like using narrowhg with multiple
treemanifest revlogs.
parent af023b09ba52
No related branches found
No related tags found
No related merge requests found
......@@ -86,9 +86,12 @@
self._always = False
self._pathrestricted = bool(include or exclude or patterns)
self._warn = warn
self._includeroots = set()
self._includedirs = set(['.'])
self._excluderoots = set()
matchfns = []
if include:
kindpats = self._normalize(include, 'glob', root, cwd, auditor)
self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
listsubrepos)
......@@ -89,11 +92,14 @@
matchfns = []
if include:
kindpats = self._normalize(include, 'glob', root, cwd, auditor)
self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
listsubrepos)
self._includeroots.update(_roots(kindpats))
self._includeroots.discard('.')
self._includedirs.update(util.dirs(self._includeroots))
matchfns.append(im)
if exclude:
kindpats = self._normalize(exclude, 'glob', root, cwd, auditor)
self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
listsubrepos)
......@@ -95,8 +101,10 @@
matchfns.append(im)
if exclude:
kindpats = self._normalize(exclude, 'glob', root, cwd, auditor)
self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)',
listsubrepos)
self._excluderoots.update(_roots(kindpats))
self._excluderoots.discard('.')
matchfns.append(lambda f: not em(f))
if exact:
if isinstance(patterns, list):
......@@ -177,6 +185,21 @@
return set(util.dirs(self._fileroots)) | set(['.'])
def visitdir(self, dir):
'''Decides whether a directory should be visited based on whether it
has potential matches in it or one of its subdirectories. This is
based on the match's primary, included, and excluded patterns.
This function's behavior is undefined if it has returned False for
one of the dir's parent directories.
'''
if dir in self._excluderoots:
return False
parentdirs = None
if (self._includeroots and dir not in self._includeroots and
dir not in self._includedirs):
parentdirs = util.finddirs(dir)
if not any(parent in self._includeroots for parent in parentdirs):
return False
return (not self._fileroots or '.' in self._fileroots or
dir in self._fileroots or dir in self._dirs or
any(parentdir in self._fileroots
......@@ -180,7 +203,7 @@
return (not self._fileroots or '.' in self._fileroots or
dir in self._fileroots or dir in self._dirs or
any(parentdir in self._fileroots
for parentdir in util.finddirs(dir)))
for parentdir in parentdirs or util.finddirs(dir)))
def exact(self, f):
'''Returns True if f is in .files().'''
......
......@@ -280,3 +280,100 @@
0 0 125 0 4 63c9c0557d24 000000000000 000000000000
1 125 109 0 5 23d12a1f6e0e 000000000000 000000000000
2 234 55 0 6 3cb2d87b4250 23d12a1f6e0e 000000000000
Create deeper repo with tree manifests.
$ cd ..
$ hg --config experimental.treemanifest=True init deeprepo
$ cd deeprepo
$ mkdir a
$ mkdir b
$ mkdir b/bar
$ mkdir b/bar/orange
$ mkdir b/bar/orange/fly
$ mkdir b/foo
$ mkdir b/foo/apple
$ mkdir b/foo/apple/bees
$ touch a/one.txt
$ touch a/two.txt
$ touch b/bar/fruits.txt
$ touch b/bar/orange/fly/gnat.py
$ touch b/bar/orange/fly/housefly.txt
$ touch b/foo/apple/bees/flower.py
$ touch c.txt
$ touch d.py
$ hg ci -Aqm 'initial'
We'll see that visitdir works by removing some treemanifest revlogs and running
the files command with various parameters.
Test files from the root.
$ hg files -r .
a/one.txt
a/two.txt
b/bar/fruits.txt
b/bar/orange/fly/gnat.py
b/bar/orange/fly/housefly.txt
b/foo/apple/bees/flower.py
c.txt
d.py
Test files for a subdirectory.
$ mv .hg/store/meta/a oldmf
$ hg files -r . b
b/bar/fruits.txt
b/bar/orange/fly/gnat.py
b/bar/orange/fly/housefly.txt
b/foo/apple/bees/flower.py
$ mv oldmf .hg/store/meta/a
Test files with just includes and excludes.
$ 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
b/bar/fruits.txt
$ mv oldmf .hg/store/meta/a
$ mv oldmf2 .hg/store/meta/b/bar/orange/fly
$ mv oldmf3 .hg/store/meta/b/foo/apple/bees
Test files for a subdirectory, excluding a directory within it.
$ mv .hg/store/meta/a oldmf
$ mv .hg/store/meta/b/foo oldmf2
$ hg files -r . -X b/foo b
b/bar/fruits.txt
b/bar/orange/fly/gnat.py
b/bar/orange/fly/housefly.txt
$ mv oldmf .hg/store/meta/a
$ mv oldmf2 .hg/store/meta/b/foo
Test files for a sub directory, including only a directory within it, and
including an unrelated directory.
$ mv .hg/store/meta/a oldmf
$ mv .hg/store/meta/b/foo oldmf2
$ hg files -r . -I b/bar/orange -I a b
b/bar/orange/fly/gnat.py
b/bar/orange/fly/housefly.txt
$ mv oldmf .hg/store/meta/a
$ mv oldmf2 .hg/store/meta/b/foo
Test files for a pattern, including a directory, and excluding a directory
within that.
$ 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
b/bar/fruits.txt
$ mv oldmf .hg/store/meta/a
$ mv oldmf2 .hg/store/meta/b/foo
$ mv oldmf3 .hg/store/meta/b/bar/orange
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment