match: resolve filesets against the passed `cwd`, not the current one
This allows filesets to be resolved relative to `repo.root`, the same as other
patterns are since f02d3c0eed18. The current example in contrib/ wasn't working
from the tests directory because of this.
Differential Revision: https://phab.mercurial-scm.org/D7570
--- a/hgext/highlight/__init__.py Thu Dec 12 14:28:31 2019 -0800
+++ b/hgext/highlight/__init__.py Fri Dec 06 20:40:02 2019 -0500
@@ -52,7 +52,7 @@
filenameonly = web.configbool(b'web', b'highlightonlymatchfilename', False)
ctx = fctx.changectx()
- m = ctx.matchfileset(expr)
+ m = ctx.matchfileset(fctx.repo().root, expr)
if m(fctx.path()):
highlight.pygmentize(
field, fctx, style, tmpl, guessfilenameonly=filenameonly
--- a/mercurial/context.py Thu Dec 12 14:28:31 2019 -0800
+++ b/mercurial/context.py Fri Dec 06 20:40:02 2019 -0500
@@ -200,8 +200,8 @@
def mutable(self):
return self.phase() > phases.public
- def matchfileset(self, expr, badfn=None):
- return fileset.match(self, expr, badfn=badfn)
+ def matchfileset(self, cwd, expr, badfn=None):
+ return fileset.match(self, cwd, expr, badfn=badfn)
def obsolete(self):
"""True if the changeset is obsolete"""
@@ -328,11 +328,14 @@
default=b'glob',
listsubrepos=False,
badfn=None,
+ cwd=None,
):
r = self._repo
+ if not cwd:
+ cwd = r.getcwd()
return matchmod.match(
r.root,
- r.getcwd(),
+ cwd,
pats,
include,
exclude,
@@ -1694,15 +1697,18 @@
default=b'glob',
listsubrepos=False,
badfn=None,
+ cwd=None,
):
r = self._repo
+ if not cwd:
+ cwd = r.getcwd()
# Only a case insensitive filesystem needs magic to translate user input
# to actual case in the filesystem.
icasefs = not util.fscasesensitive(r.root)
return matchmod.match(
r.root,
- r.getcwd(),
+ cwd,
pats,
include,
exclude,
--- a/mercurial/debugcommands.py Thu Dec 12 14:28:31 2019 -0800
+++ b/mercurial/debugcommands.py Fri Dec 06 20:40:02 2019 -0500
@@ -1171,7 +1171,7 @@
files.update(ctx.files())
files.update(ctx.substate)
- m = ctx.matchfileset(expr)
+ m = ctx.matchfileset(repo.getcwd(), expr)
if opts[b'show_matcher'] or (opts[b'show_matcher'] is None and ui.verbose):
ui.writenoi18n(b'* matcher:\n', stringutil.prettyrepr(m), b'\n')
for f in sorted(files):
--- a/mercurial/fileset.py Thu Dec 12 14:28:31 2019 -0800
+++ b/mercurial/fileset.py Fri Dec 06 20:40:02 2019 -0500
@@ -520,29 +520,30 @@
class matchctx(object):
- def __init__(self, basectx, ctx, badfn=None):
+ def __init__(self, basectx, ctx, cwd, badfn=None):
self._basectx = basectx
self.ctx = ctx
self._badfn = badfn
self._match = None
self._status = None
+ self.cwd = cwd
def narrowed(self, match):
"""Create matchctx for a sub-tree narrowed by the given matcher"""
- mctx = matchctx(self._basectx, self.ctx, self._badfn)
+ mctx = matchctx(self._basectx, self.ctx, self.cwd, self._badfn)
mctx._match = match
# leave wider status which we don't have to care
mctx._status = self._status
return mctx
def switch(self, basectx, ctx):
- mctx = matchctx(basectx, ctx, self._badfn)
+ mctx = matchctx(basectx, ctx, self.cwd, self._badfn)
mctx._match = self._match
return mctx
def withstatus(self, keys):
"""Create matchctx which has precomputed status specified by the keys"""
- mctx = matchctx(self._basectx, self.ctx, self._badfn)
+ mctx = matchctx(self._basectx, self.ctx, self.cwd, self._badfn)
mctx._match = self._match
mctx._buildstatus(keys)
return mctx
@@ -560,7 +561,7 @@
return self._status
def matcher(self, patterns):
- return self.ctx.match(patterns, badfn=self._badfn)
+ return self.ctx.match(patterns, badfn=self._badfn, cwd=self.cwd)
def predicate(self, predfn, predrepr=None, cache=False):
"""Create a matcher to select files by predfn(filename)"""
@@ -617,12 +618,12 @@
return matchmod.never(badfn=self._badfn)
-def match(ctx, expr, badfn=None):
+def match(ctx, cwd, expr, badfn=None):
"""Create a matcher for a single fileset expression"""
tree = filesetlang.parse(expr)
tree = filesetlang.analyze(tree)
tree = filesetlang.optimize(tree)
- mctx = matchctx(ctx.p1(), ctx, badfn=badfn)
+ mctx = matchctx(ctx.p1(), ctx, cwd, badfn=badfn)
return getmatch(mctx, tree)
--- a/mercurial/match.py Thu Dec 12 14:28:31 2019 -0800
+++ b/mercurial/match.py Fri Dec 06 20:40:02 2019 -0500
@@ -57,7 +57,7 @@
return m.match
-def _expandsets(kindpats, ctx=None, listsubrepos=False, badfn=None):
+def _expandsets(cwd, kindpats, ctx=None, listsubrepos=False, badfn=None):
'''Returns the kindpats list with the 'set' patterns expanded to matchers'''
matchers = []
other = []
@@ -68,11 +68,11 @@
raise error.ProgrammingError(
b"fileset expression with no context"
)
- matchers.append(ctx.matchfileset(pat, badfn=badfn))
+ matchers.append(ctx.matchfileset(cwd, pat, badfn=badfn))
if listsubrepos:
for subpath in ctx.substate:
- sm = ctx.sub(subpath).matchfileset(pat, badfn=badfn)
+ sm = ctx.sub(subpath).matchfileset(cwd, pat, badfn=badfn)
pm = prefixdirmatcher(subpath, sm, badfn=badfn)
matchers.append(pm)
@@ -117,11 +117,11 @@
def _buildkindpatsmatcher(
- matchercls, root, kindpats, ctx=None, listsubrepos=False, badfn=None
+ matchercls, root, cwd, kindpats, ctx=None, listsubrepos=False, badfn=None,
):
matchers = []
fms, kindpats = _expandsets(
- kindpats, ctx=ctx, listsubrepos=listsubrepos, badfn=badfn
+ cwd, kindpats, ctx=ctx, listsubrepos=listsubrepos, badfn=badfn,
)
if kindpats:
m = matchercls(root, kindpats, badfn=badfn)
@@ -261,6 +261,7 @@
m = _buildkindpatsmatcher(
patternmatcher,
root,
+ cwd,
kindpats,
ctx=ctx,
listsubrepos=listsubrepos,
@@ -276,6 +277,7 @@
im = _buildkindpatsmatcher(
includematcher,
root,
+ cwd,
kindpats,
ctx=ctx,
listsubrepos=listsubrepos,
@@ -287,6 +289,7 @@
em = _buildkindpatsmatcher(
includematcher,
root,
+ cwd,
kindpats,
ctx=ctx,
listsubrepos=listsubrepos,
--- a/mercurial/subrepo.py Thu Dec 12 14:28:31 2019 -0800
+++ b/mercurial/subrepo.py Fri Dec 06 20:40:02 2019 -0500
@@ -355,7 +355,7 @@
"""return file flags"""
return b''
- def matchfileset(self, expr, badfn=None):
+ def matchfileset(self, cwd, expr, badfn=None):
"""Resolve the fileset expression for this repo"""
return matchmod.never(badfn=badfn)
@@ -896,20 +896,20 @@
return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt, subrepos)
@annotatesubrepoerror
- def matchfileset(self, expr, badfn=None):
+ def matchfileset(self, cwd, expr, badfn=None):
if self._ctx.rev() is None:
ctx = self._repo[None]
else:
rev = self._state[1]
ctx = self._repo[rev]
- matchers = [ctx.matchfileset(expr, badfn=badfn)]
+ matchers = [ctx.matchfileset(cwd, expr, badfn=badfn)]
for subpath in ctx.substate:
sub = ctx.sub(subpath)
try:
- sm = sub.matchfileset(expr, badfn=badfn)
+ sm = sub.matchfileset(cwd, expr, badfn=badfn)
pm = matchmod.prefixdirmatcher(subpath, sm, badfn=badfn)
matchers.append(pm)
except error.LookupError:
--- a/tests/test-fix.t Thu Dec 12 14:28:31 2019 -0800
+++ b/tests/test-fix.t Fri Dec 06 20:40:02 2019 -0500
@@ -1335,24 +1335,20 @@
Apparently fixing p1() and its descendants doesn't include wdir() unless
explicitly stated.
-BROKEN: fileset matches aren't relative to repo.root for commits
-
$ hg fix -r '.::'
$ hg cat -r . ../quux
quux
$ hg cat -r tip ../quux
- quux
+ fs: $TESTTMP/subprocesscwd
$ cat ../quux
quux
Clean files are not fixed unless explicitly named
$ echo 'dirty' > ../quux
-BROKEN: fileset matches aren't relative to repo.root for wdir
-
$ hg fix --working-dir
$ cat ../quux
- dirty
+ fs: $TESTTMP/subprocesscwd
$ cd ../..