[PATCH 3 of 3] (RFC) scmutil: proxy revrange() through repo to break import cycles

Yuya Nishihara yuya at tcha.org
Sun Feb 19 08:12:06 EST 2017


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1487502018 -32400
#      Sun Feb 19 20:00:18 2017 +0900
# Node ID fd48908e928243b8d06faaef518f1b862d8f2579
# Parent  85ab530251b2810e18339c13a0f95a4f02d7ab3a
(RFC) scmutil: proxy revrange() through repo to break import cycles

This was one of the hardest import cycles as scmutil is widely used and
revset functions are likely to depend on a variety of modules.

New repo.anyrevs() does not expand user aliases by default to copy the
behavior of the existing repo.revs(). I don't want to add new function to
localrepository, but this function is quite similar to repo.revs() so it
won't increase the complexity of the localrepository class so much.

diff --git a/mercurial/destutil.py b/mercurial/destutil.py
--- a/mercurial/destutil.py
+++ b/mercurial/destutil.py
@@ -12,6 +12,7 @@ from . import (
     bookmarks,
     error,
     obsolete,
+    scmutil,
 )
 
 def _destupdateobs(repo, clean):
@@ -342,9 +343,6 @@ histeditdefaultrevset = 'reverse(only(.)
 
 def desthistedit(ui, repo):
     """Default base revision to edit for `hg histedit`."""
-    # Avoid cycle: scmutil -> revset -> destutil
-    from . import scmutil
-
     default = ui.config('histedit', 'defaultrev', histeditdefaultrevset)
     if default:
         revs = scmutil.revrange(repo, [default])
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -577,7 +577,8 @@ class localrepository(object):
         %-formatting to escape certain types. See ``revsetlang.formatspec``.
 
         Revset aliases from the configuration are not expanded. To expand
-        user aliases, consider calling ``scmutil.revrange()``.
+        user aliases, consider calling ``scmutil.revrange()`` or
+        ``repo.anyrevs([expr], user=True)``.
 
         Returns a revset.abstractsmartset, which is a list-like interface
         that contains integer revisions.
@@ -598,6 +599,18 @@ class localrepository(object):
         for r in self.revs(expr, *args):
             yield self[r]
 
+    def anyrevs(self, specs, user=False):
+        '''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``.
+        '''
+        if user:
+            m = revset.matchany(self.ui, specs, repo=self)
+        else:
+            m = revset.matchany(None, specs)
+        return m(self)
+
     def url(self):
         return 'file:' + self.root
 
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -29,7 +29,6 @@ from . import (
     pathutil,
     phases,
     pycompat,
-    revset,
     revsetlang,
     similar,
     util,
@@ -950,8 +949,7 @@ def revrange(repo, specs):
         if isinstance(spec, int):
             spec = revsetlang.formatspec('rev(%d)', spec)
         allspecs.append(spec)
-    m = revset.matchany(repo.ui, allspecs, repo)
-    return m(repo)
+    return repo.anyrevs(allspecs, user=True)
 
 def meaningfulparents(repo, ctx):
     """Return list of meaningful (or all if debug) parentrevs for rev.
diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -24,6 +24,7 @@ from .node import (
 from . import (
     encoding,
     error,
+    scmutil,
     util,
 )
 
@@ -277,8 +278,6 @@ def _readtagcache(ui, repo):
     If the cache is not up to date, the caller is responsible for reading tag
     info from each returned head. (See findglobaltags().)
     '''
-    from . import scmutil  # avoid cycle
-
     try:
         cachefile = repo.vfs(_filename(repo), 'r')
         # force reading the file for static-http


More information about the Mercurial-devel mailing list