diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -1065,7 +1065,9 @@ def _matchfiles(repo, subset, x): if rev is not None: raise error.ParseError('_matchfiles expected at most one ' 'revision') - if value != '': # empty means working directory; leave rev as None + if value == '': # empty means working directory + rev = node.wdirrev + else: rev = value elif prefix == 'd:': if default is not None: @@ -1076,9 +1078,9 @@ def _matchfiles(repo, subset, x): raise error.ParseError('invalid _matchfiles prefix: %s' % prefix) if not default: default = 'glob' + hasset = any(matchmod.patkind(p) == 'set' for p in pats + inc + exc) - m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc, - exclude=exc, ctx=repo[rev], default=default) + mcache = [None] # This directly read the changelog data as creating changectx for all # revisions is quite expensive. @@ -1089,6 +1091,14 @@ def _matchfiles(repo, subset, x): files = repo[x].files() else: files = getfiles(x) + + if not mcache[0] or (hasset and rev is None): + r = x if rev is None else rev + mcache[0] = matchmod.match(repo.root, repo.getcwd(), pats, + include=inc, exclude=exc, ctx=repo[r], + default=default) + m = mcache[0] + for f in files: if m(f): return True diff --git a/tests/test-glog.t b/tests/test-glog.t --- a/tests/test-glog.t +++ b/tests/test-glog.t @@ -1675,7 +1675,7 @@ Test falling back to slow path for non-e (string 'p:c'))) , - > + > Test multiple --include/--exclude/paths @@ -1694,7 +1694,7 @@ Test multiple --include/--exclude/paths (string 'x:e'))) , - > + > Test glob expansion of pats @@ -1732,7 +1732,7 @@ Test --follow on a directory (string 'p:dir'))) , - > + > $ hg up -q tip Test --follow on file not in parent revision @@ -1754,7 +1754,7 @@ Test --follow and patterns (string 'p:glob:*'))) , - > + > Test --follow on a single rename @@ -1875,7 +1875,7 @@ Test "set:..." and parent revision (string 'p:set:copied()'))) , - > + > $ testlog --include "set:copied()" [] (func @@ -1886,11 +1886,13 @@ Test "set:..." and parent revision (string 'i:set:copied()'))) , - > + > $ testlog -r "sort(file('set:copied()'), -rev)" ["sort(file('set:copied()'), -rev)"] [] - + , + > Test --removed @@ -1908,7 +1910,7 @@ Test --removed (string 'p:a'))) , - > + > $ testlog --removed --follow a [] (func @@ -1919,7 +1921,7 @@ Test --removed (string 'p:a'))) , - > + > Test --patch and --stat with --follow and --follow-first @@ -2290,7 +2292,7 @@ Test subdir (string 'p:.'))) , - > + > $ testlog ../b [] (func diff --git a/tests/test-largefiles-update.t b/tests/test-largefiles-update.t --- a/tests/test-largefiles-update.t +++ b/tests/test-largefiles-update.t @@ -726,6 +726,20 @@ bit correctly on the platform being unaw #endif +The fileset revset is evaluated for each revision, instead of once on wdir(), +and then patterns matched on each revision. Here, no exec bits are set in +wdir(), but a matching revision is detected. + +(Teach large2 is not an executable. Maybe this is a bug of largefiles.) +#if execbit + $ chmod -x .hglf/large2 +#endif + + $ hg files 'set:exec()' + [1] + $ hg log -qr 'file("set:exec()")' + 9:be1b433a65b1 + Test a fatal error interrupting an update. Verify that status report dirty files correctly after an interrupted update. Also verify that checking all hashes reveals it isn't clean.