# HG changeset patch # User Yuya Nishihara # Date 1516108473 -32400 # Node ID 821d8a5ab4ff890a7732c2e4cdcc7f32191e5942 # Parent a1222a8cc93b793e8dd1fb9821d19bf53e096da9 match: do not weirdly include explicit files excluded by -X option Actually, this was the original behavior. Before a83a7d27911e, "log" and "files" showed nothing if "FILE -X FILE" was specified, whereas "debugwalk" got confused by an explicit FILE pattern. Under the hood, "log" and "files" use m() and ctx.matches(m) respectively, and "debugwalk" uses ctx.walk(m). I suspect dirstate.walk() goes wrong in _walkexplicit(), which seems to blindly trust m.files(). I reckon the original "log"/"files" behavior is correct, and drop the hack from the differencematcher. diff -r a1222a8cc93b -r 821d8a5ab4ff mercurial/match.py --- a/mercurial/match.py Sun Jan 14 15:56:22 2018 -0500 +++ b/mercurial/match.py Tue Jan 16 22:14:33 2018 +0900 @@ -457,17 +457,10 @@ class differencematcher(basematcher): '''Composes two matchers by matching if the first matches and the second - does not. Well, almost... If the user provides a pattern like "-X foo foo", - Mercurial actually does match "foo" against that. That's because exact - matches are treated specially. So, since this differencematcher is used for - excludes, it needs to special-case exact matching. + does not. The second matcher's non-matching-attributes (root, cwd, bad, explicitdir, traversedir) are ignored. - - TODO: If we want to keep the behavior described above for exact matches, we - should consider instead treating the above case something like this: - union(exact(foo), difference(pattern(foo), include(foo))) ''' def __init__(self, m1, m2): super(differencematcher, self).__init__(m1._root, m1._cwd) @@ -478,7 +471,7 @@ self.traversedir = m1.traversedir def matchfn(self, f): - return self._m1(f) and (not self._m2(f) or self._m1.exact(f)) + return self._m1(f) and not self._m2(f) @propertycache def _files(self): @@ -493,9 +486,6 @@ def visitdir(self, dir): if self._m2.visitdir(dir) == 'all': - # There's a bug here: If m1 matches file 'dir/file' and m2 excludes - # 'dir' (recursively), we should still visit 'dir' due to the - # exception we have for exact matches. return False return bool(self._m1.visitdir(dir)) diff -r a1222a8cc93b -r 821d8a5ab4ff tests/test-locate.t --- a/tests/test-locate.t Sun Jan 14 15:56:22 2018 -0500 +++ b/tests/test-locate.t Tue Jan 16 22:14:33 2018 +0900 @@ -103,6 +103,11 @@ $ hg files b b +-X with explicit path: + + $ hg files b -X b + [1] + $ mkdir otherdir $ cd otherdir diff -r a1222a8cc93b -r 821d8a5ab4ff tests/test-log.t --- a/tests/test-log.t Sun Jan 14 15:56:22 2018 -0500 +++ b/tests/test-log.t Tue Jan 16 22:14:33 2018 +0900 @@ -102,6 +102,10 @@ summary: c +-X, with explicit path + + $ hg log a -X a + -f, non-existent directory $ hg log -f dir diff -r a1222a8cc93b -r 821d8a5ab4ff tests/test-walk.t --- a/tests/test-walk.t Sun Jan 14 15:56:22 2018 -0500 +++ b/tests/test-walk.t Tue Jan 16 22:14:33 2018 +0900 @@ -344,6 +344,21 @@ abort: path 'beans/.hg' is inside nested repo 'beans' [255] +Test explicit paths and excludes: +(BROKEN: nothing should be included, but wctx.walk() does) + + $ hg debugwalk fennel -X fennel + matcher: , m2=> + f fennel fennel exact + $ hg debugwalk fennel -X 'f*' + matcher: , m2=> + f fennel fennel exact + $ hg debugwalk beans/black -X 'path:beans' + matcher: , m2=> + f beans/black beans/black exact + $ hg debugwalk -I 'path:beans/black' -X 'path:beans' + matcher: , m2=> + Test absolute paths: $ hg debugwalk `pwd`/beans