revset: make repo.anyrevs accept customized alias override (API)
Previously repo.anyrevs only expand aliases in [revsetalias] config. This
patch makes it more flexible to accept a customized dict defining aliases
without having to couple with ui.
revsetlang.expandaliases now has the signature (tree, aliases, warn=None)
which is more consistent with templater.expandaliases. revsetlang.py is now
free from "ui", which seems to be a good thing.
--- a/mercurial/debugcommands.py Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/debugcommands.py Sat Jun 24 15:29:42 2017 -0700
@@ -1960,9 +1960,11 @@
one. Returns 1 if the optimized result differs.
"""
opts = pycompat.byteskwargs(opts)
+ aliases = ui.configitems('revsetalias')
stages = [
('parsed', lambda tree: tree),
- ('expanded', lambda tree: revsetlang.expandaliases(ui, tree)),
+ ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
+ ui.warn)),
('concatenated', revsetlang.foldconcat),
('analyzed', revsetlang.analyze),
('optimized', revsetlang.optimize),
--- a/mercurial/localrepo.py Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/localrepo.py Sat Jun 24 15:29:42 2017 -0700
@@ -648,16 +648,19 @@
for r in self.revs(expr, *args):
yield self[r]
- def anyrevs(self, specs, user=False):
+ def anyrevs(self, specs, user=False, localalias=None):
'''Find revisions matching one of the given revsets.
Revset aliases from the configuration are not expanded by default. To
- expand user aliases, specify ``user=True``.
+ expand user aliases, specify ``user=True``. To provide some local
+ definitions overriding user aliases, set ``localalias`` to
+ ``{name: definitionstring}``.
'''
if user:
- m = revset.matchany(self.ui, specs, repo=self)
+ m = revset.matchany(self.ui, specs, repo=self,
+ localalias=localalias)
else:
- m = revset.matchany(None, specs)
+ m = revset.matchany(None, specs, localalias=localalias)
return m(self)
def url(self):
--- a/mercurial/revset.py Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/revset.py Sat Jun 24 15:29:42 2017 -0700
@@ -2001,12 +2001,15 @@
"""
return matchany(ui, [spec], repo=repo, order=order)
-def matchany(ui, specs, repo=None, order=defineorder):
+def matchany(ui, specs, repo=None, order=defineorder, localalias=None):
"""Create a matcher that will include any revisions matching one of the
given specs
If order=followorder, a matcher takes the ordering specified by the input
set.
+
+ If localalias is not None, it is a dict {name: definitionstring}. It takes
+ precedence over [revsetalias] config section.
"""
if not specs:
def mfunc(repo, subset=None):
@@ -2023,8 +2026,15 @@
tree = ('or',
('list',) + tuple(revsetlang.parse(s, lookup) for s in specs))
+ aliases = []
+ warn = None
if ui:
- tree = revsetlang.expandaliases(ui, tree)
+ aliases.extend(ui.configitems('revsetalias'))
+ warn = ui.warn
+ if localalias:
+ aliases.extend(localalias.items())
+ if aliases:
+ tree = revsetlang.expandaliases(tree, aliases, warn=warn)
tree = revsetlang.foldconcat(tree)
tree = revsetlang.analyze(tree, order)
tree = revsetlang.optimize(tree)
--- a/mercurial/revsetlang.py Fri Jul 07 01:05:20 2017 -0400
+++ b/mercurial/revsetlang.py Sat Jun 24 15:29:42 2017 -0700
@@ -561,14 +561,16 @@
if tree[0] == 'func' and tree[1][0] == 'symbol':
return tree[1][1], getlist(tree[2])
-def expandaliases(ui, tree):
- aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))
+def expandaliases(tree, aliases, warn=None):
+ """Expand aliases in a tree, aliases is a list of (name, value) tuples"""
+ aliases = _aliasrules.buildmap(aliases)
tree = _aliasrules.expand(aliases, tree)
# warn about problematic (but not referred) aliases
- for name, alias in sorted(aliases.iteritems()):
- if alias.error and not alias.warned:
- ui.warn(_('warning: %s\n') % (alias.error))
- alias.warned = True
+ if warn is not None:
+ for name, alias in sorted(aliases.iteritems()):
+ if alias.error and not alias.warned:
+ warn(_('warning: %s\n') % (alias.error))
+ alias.warned = True
return tree
def foldconcat(tree):
--- a/tests/test-revset.t Fri Jul 07 01:05:20 2017 -0400
+++ b/tests/test-revset.t Sat Jun 24 15:29:42 2017 -0700
@@ -4259,4 +4259,27 @@
hg: parse error: unknown identifier: custom1
[255]
+Test repo.anyrevs with customized revset overrides
+
+ $ cat > $TESTTMP/printprevset.py <<EOF
+ > from mercurial import encoding
+ > def reposetup(ui, repo):
+ > alias = {}
+ > p = encoding.environ.get('P')
+ > if p:
+ > alias['P'] = p
+ > revs = repo.anyrevs(['P'], user=True, localalias=alias)
+ > ui.write('P=%r' % list(revs))
+ > EOF
+
+ $ cat >> .hg/hgrc <<EOF
+ > custompredicate = !
+ > printprevset = $TESTTMP/printprevset.py
+ > EOF
+
+ $ hg --config revsetalias.P=1 log -r . -T '\n'
+ P=[1]
+ $ P=3 hg --config revsetalias.P=2 log -r . -T '\n'
+ P=[3]
+
$ cd ..