[PATCH V2] revset: make repo.anyrevs accept customized alias override (API)

Jun Wu quark at fb.com
Sat Jul 8 02:18:53 UTC 2017


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1498343382 25200
#      Sat Jun 24 15:29:42 2017 -0700
# Node ID 3a01f8dc2cc144c979134840d6148946fb6f1a0f
# Parent  e714159860fd0872ae0555bb07546aa7e9f700e0
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 3a01f8dc2cc1
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.

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -1961,7 +1961,9 @@ def debugrevspec(ui, repo, expr, **opts)
     """
     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),
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -649,14 +649,17 @@ class localrepository(object):
             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)
 
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2002,5 +2002,5 @@ def match(ui, spec, repo=None, order=def
     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
@@ -2008,4 +2008,7 @@ def matchany(ui, specs, repo=None, order
     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:
@@ -2024,6 +2027,13 @@ def matchany(ui, specs, repo=None, order
                 ('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)
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -562,12 +562,14 @@ class _aliasrules(parser.basealiasrules)
             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
 
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -4260,3 +4260,26 @@ loading it
   [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 ..


More information about the Mercurial-devel mailing list