From patchwork Wed Jan 8 17:22:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: D7570: match: resolve filesets against the passed `cwd`, not the current one From: phabricator X-Patchwork-Id: 44184 Message-Id: <0590a4a27aca12276e28df8bb74ffff6@localhost.localdomain> To: Phabricator Cc: mercurial-devel@mercurial-scm.org Date: Wed, 8 Jan 2020 17:22:14 +0000 Closed by commit rHG28ea223a65c5: match: resolve filesets against the passed `cwd`, not the current one (authored by mharbison72). This revision was automatically updated to reflect the committed changes. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7570?vs=19072&id=19073 CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7570/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7570 AFFECTED FILES hgext/highlight/__init__.py mercurial/context.py mercurial/debugcommands.py mercurial/fileset.py mercurial/match.py mercurial/subrepo.py tests/test-fix.t CHANGE DETAILS To: mharbison72, #hg-reviewers, durin42 Cc: durin42, hooper, yuja, martinvonz, mercurial-devel diff --git a/tests/test-fix.t b/tests/test-fix.t --- a/tests/test-fix.t +++ b/tests/test-fix.t @@ -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 ../.. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -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: diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -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, diff --git a/mercurial/fileset.py b/mercurial/fileset.py --- a/mercurial/fileset.py +++ b/mercurial/fileset.py @@ -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) diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -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): diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -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, diff --git a/hgext/highlight/__init__.py b/hgext/highlight/__init__.py --- a/hgext/highlight/__init__.py +++ b/hgext/highlight/__init__.py @@ -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