Patchwork D11560: errors: raise InputError on bad revset to revrange() iff provided by the user

login
register
mail settings
Submitter phabricator
Date Oct. 1, 2021, 7:59 p.m.
Message ID <differential-rev-PHID-DREV-kgrleemxdj7swhobgnif-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49886/
State Superseded
Headers show

Comments

phabricator - Oct. 1, 2021, 7:59 p.m.
martinvonz created this revision.
Herald added a reviewer: durin42.
Herald added subscribers: mercurial-patches, Kwan.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Most callers of `scmutil.revrange()` pass in a revset provided by the
  user. If there are problems resolving that, it should result in an
  `InputError` and exit code 10 (when using detailed exit
  codes). However, there are also some callers that pass in revsets not
  provided by the user. `InputError` is not appropriate in those
  cases. This patch therefore introduces a wrapper around
  `scmutil.revrange()` that simply converts the exception type. I put it
  in `logcmdutil.py` since that seems to be the lowest-level module in
  the (poorly defined) UI layer.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D11560

AFFECTED FILES
  contrib/synthrepo.py
  hgext/closehead.py
  hgext/convert/hg.py
  hgext/fastexport.py
  hgext/fix.py
  hgext/histedit.py
  hgext/largefiles/lfcommands.py
  hgext/largefiles/overrides.py
  hgext/lfs/__init__.py
  hgext/mq.py
  hgext/patchbomb.py
  hgext/phabricator.py
  hgext/rebase.py
  hgext/releasenotes.py
  hgext/split.py
  hgext/transplant.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/debugcommands.py
  mercurial/hg.py
  mercurial/logcmdutil.py
  mercurial/strip.py
  tests/test-bookmarks.t
  tests/test-branch-change.t
  tests/test-directaccess.t
  tests/test-export.t
  tests/test-log.t
  tests/test-logexchange.t
  tests/test-mq-qdelete.t
  tests/test-obsolete.t
  tests/test-revset-legacy-lookup.t
  tests/test-revset.t
  tests/test-revset2.t

CHANGE DETAILS




To: martinvonz, durin42, #hg-reviewers
Cc: Kwan, mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-revset2.t b/tests/test-revset2.t
--- a/tests/test-revset2.t
+++ b/tests/test-revset2.t
@@ -320,7 +320,7 @@ 
 
   $ log '0|unknown'
   abort: unknown revision 'unknown'
-  [255]
+  [10]
 
 test integer range in `_list`
 
@@ -330,11 +330,11 @@ 
 
   $ log '-10|-11'
   abort: unknown revision '-11'
-  [255]
+  [10]
 
   $ log '9|10'
   abort: unknown revision '10'
-  [255]
+  [10]
 
 test '0000' != '0' in `_list`
 
@@ -590,7 +590,7 @@ 
 
   $ log 'tag("1..*")'
   abort: tag '1..*' does not exist
-  [255]
+  [10]
   $ log 'tag("re:1..*")'
   6
   $ log 'tag("re:[0-9].[0-9]")'
@@ -601,16 +601,16 @@ 
 
   $ log 'tag(unknown)'
   abort: tag 'unknown' does not exist
-  [255]
+  [10]
   $ log 'tag("re:unknown")'
   $ log 'present(tag("unknown"))'
   $ log 'present(tag("re:unknown"))'
   $ log 'branch(unknown)'
   abort: unknown revision 'unknown'
-  [255]
+  [10]
   $ log 'branch("literal:unknown")'
   abort: branch 'unknown' does not exist
-  [255]
+  [10]
   $ log 'branch("re:unknown")'
   $ log 'present(branch("unknown"))'
   $ log 'present(branch("re:unknown"))'
@@ -666,7 +666,7 @@ 
 
   $ log 'named("unknown")'
   abort: namespace 'unknown' does not exist
-  [255]
+  [10]
   $ log 'named("re:unknown")'
   $ log 'present(named("unknown"))'
   $ log 'present(named("re:unknown"))'
@@ -759,7 +759,7 @@ 
 
   $ log 'branchpoint()~-1'
   abort: revision in set has more than one child
-  [255]
+  [10]
 
 Bogus function gets suggestions
   $ log 'add()'
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -407,7 +407,7 @@ 
   [10]
   $ log 'date'
   abort: unknown revision 'date'
-  [255]
+  [10]
   $ log 'date('
   hg: parse error at 5: not a prefix: end
   (date(
@@ -421,10 +421,10 @@ 
   [10]
   $ log '0:date'
   abort: unknown revision 'date'
-  [255]
+  [10]
   $ log '::"date"'
   abort: unknown revision 'date'
-  [255]
+  [10]
   $ hg book date -r 4
   $ log '0:date'
   0
@@ -3067,7 +3067,7 @@ 
   0
   $ log 'expectsize(0:1, 1)'
   abort: revset size mismatch. expected 1, got 2
-  [255]
+  [10]
   $ log 'expectsize(0:4, -1)'
   hg: parse error: negative size
   [10]
@@ -3077,7 +3077,7 @@ 
   2
   $ log 'expectsize(0:1, 3:5)'
   abort: revset size mismatch. expected between 3 and 5, got 2
-  [255]
+  [10]
   $ log 'expectsize(0:1, -1:2)'
   hg: parse error: negative size
   [10]
@@ -3104,10 +3104,10 @@ 
   2
   $ log 'expectsize(0:2, 4:)'
   abort: revset size mismatch. expected between 4 and 11, got 3
-  [255]
+  [10]
   $ log 'expectsize(0:2, :2)'
   abort: revset size mismatch. expected between 0 and 2, got 3
-  [255]
+  [10]
 
 Test getting list of node from file
 
diff --git a/tests/test-revset-legacy-lookup.t b/tests/test-revset-legacy-lookup.t
--- a/tests/test-revset-legacy-lookup.t
+++ b/tests/test-revset-legacy-lookup.t
@@ -96,10 +96,10 @@ 
   2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"]
   $ hg log -r '("foo")'
   abort: unknown revision 'foo'
-  [255]
+  [10]
   $ hg log -r 'revset("foo")'
   abort: unknown revision 'foo'
-  [255]
+  [10]
   $ hg log -r '("\"foo\"")'
   2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"]
   $ hg log -r 'revset("\"foo\"")'
@@ -126,10 +126,10 @@ 
   4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar]
   $ hg log -r '(foo+bar)'
   abort: unknown revision 'foo'
-  [255]
+  [10]
   $ hg log -r 'revset(foo+bar)'
   abort: unknown revision 'foo'
-  [255]
+  [10]
   $ hg log -r '"foo+bar"'
   4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar]
   $ hg log -r '("foo+bar")'
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -203,11 +203,11 @@ 
   5:5601fb93a350 (draft) [tip ] add new_3_c
   $ hg log -r 6
   abort: unknown revision '6'
-  [255]
+  [10]
   $ hg log -r 4
   abort: hidden revision '4' was rewritten as: 5601fb93a350
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
   $ hg debugrevspec 'rev(6)'
   $ hg debugrevspec 'rev(4)'
   $ hg debugrevspec 'null'
@@ -1544,7 +1544,7 @@ 
   $ hg log -r 13bedc178fce
   abort: hidden revision '13bedc178fce' was rewritten as: a9b1f8652753
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
 Empty out the test extension, as it isn't compatible with later parts
 of the test.
diff --git a/tests/test-mq-qdelete.t b/tests/test-mq-qdelete.t
--- a/tests/test-mq-qdelete.t
+++ b/tests/test-mq-qdelete.t
@@ -115,7 +115,7 @@ 
 
   $ hg qfinish -a pc
   abort: unknown revision 'pc'
-  [255]
+  [10]
 
   $ hg qpush
   applying pc
diff --git a/tests/test-logexchange.t b/tests/test-logexchange.t
--- a/tests/test-logexchange.t
+++ b/tests/test-logexchange.t
@@ -480,15 +480,15 @@ 
 
   $ hg log -r 'remotebranches(def)' -GT "{rev}:{node|short} {remotenames}\n"
   abort: remote name 'def' does not exist
-  [255]
+  [10]
 
   $ hg log -r 'remotebookmarks("server3")' -GT "{rev}:{node|short} {remotenames}\n"
   abort: remote name 'server3' does not exist
-  [255]
+  [10]
 
   $ hg log -r 'remotenames("server3")' -GT "{rev}:{node|short} {remotenames}\n"
   abort: remote name 'server3' does not exist
-  [255]
+  [10]
 
 Testing for a pattern which does not match anything, which shouldn't fail.
 
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -5,13 +5,13 @@ 
   $ hg log
   $ hg log -r 1
   abort: unknown revision '1'
-  [255]
+  [10]
   $ hg log -r -1:0
   abort: unknown revision '-1'
-  [255]
+  [10]
   $ hg log -r 'branch(name)'
   abort: unknown revision 'name'
-  [255]
+  [10]
   $ hg log -r null -q
   -1:000000000000
 
@@ -1104,7 +1104,7 @@ 
 
   $ hg log -r 1000000000000000000000000000000000000000
   abort: unknown revision '1000000000000000000000000000000000000000'
-  [255]
+  [10]
 
 log -k r1
 
@@ -2061,7 +2061,7 @@ 
   $ hg log -r a
   abort: hidden revision 'a' is pruned
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
 test that parent prevent a changeset to be hidden
 
@@ -2125,7 +2125,7 @@ 
   $ hg log -T'{rev}:{node}\n' -r:0
   abort: hidden revision '0' is pruned
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
   $ hg log -T'{rev}:{node}\n' -f
   3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
   2:94375ec45bddd2a824535fc04855bd058c926ec0
diff --git a/tests/test-export.t b/tests/test-export.t
--- a/tests/test-export.t
+++ b/tests/test-export.t
@@ -370,7 +370,7 @@ 
   [10]
   $ hg export 999
   abort: unknown revision '999'
-  [255]
+  [10]
   $ hg export "not all()"
   abort: export requires at least one changeset
   [10]
diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t
--- a/tests/test-directaccess.t
+++ b/tests/test-directaccess.t
@@ -42,7 +42,7 @@ 
   $ hg exp 2 --config experimental.directaccess.revnums=False
   abort: hidden revision '2' was rewritten as: 2443a0e66469
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
   $ hg exp 2
   # HG changeset patch
@@ -197,12 +197,12 @@ 
   $ hg phase -r 28ad74
   abort: hidden revision '28ad74' was rewritten as: 2443a0e66469
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
   $ hg phase -r 2
   abort: hidden revision '2' was rewritten as: 2443a0e66469
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
 Setting a bookmark will make that changeset unhidden, so this should come in end
 
diff --git a/tests/test-branch-change.t b/tests/test-branch-change.t
--- a/tests/test-branch-change.t
+++ b/tests/test-branch-change.t
@@ -147,7 +147,7 @@ 
   $ hg branch -r 4 foobar
   abort: hidden revision '4' was rewritten as: 7c1991464886
   (use --hidden to access hidden revisions)
-  [255]
+  [10]
 
   $ hg branch -r 4 --hidden foobar
   abort: cannot change branch of 3938acfb5c0f, as that creates content-divergence with 7c1991464886
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -185,22 +185,22 @@ 
 
   $ hg log -r 'bookmark("literal:.")'
   abort: bookmark '.' does not exist
-  [255]
+  [10]
 
 "." should fail if there's no active bookmark:
 
   $ hg bookmark --inactive
   $ hg log -r 'bookmark(.)'
   abort: no active bookmark
-  [255]
+  [10]
   $ hg log -r 'present(bookmark(.))'
 
   $ hg log -r 'bookmark(unknown)'
   abort: bookmark 'unknown' does not exist
-  [255]
+  [10]
   $ hg log -r 'bookmark("literal:unknown")'
   abort: bookmark 'unknown' does not exist
-  [255]
+  [10]
   $ hg log -r 'bookmark("re:unknown")'
   $ hg log -r 'present(bookmark("literal:unknown"))'
   $ hg log -r 'present(bookmark("re:unknown"))'
diff --git a/mercurial/strip.py b/mercurial/strip.py
--- a/mercurial/strip.py
+++ b/mercurial/strip.py
@@ -8,6 +8,7 @@ 
     error,
     hg,
     lock as lockmod,
+    logcmdutil,
     mergestate as mergestatemod,
     pycompat,
     registrar,
@@ -178,7 +179,7 @@ 
 
     cl = repo.changelog
     revs = list(revs) + opts.get(b'rev')
-    revs = set(scmutil.revrange(repo, revs))
+    revs = set(logcmdutil.revrange(repo, revs))
 
     with repo.wlock():
         bookmarks = set(opts.get(b'bookmark'))
diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -912,6 +912,18 @@ 
     return None
 
 
+def revrange(repo, specs, localalias=None):
+    """Resolves user-provided revset(s).
+
+    This just wraps the lower-level scmutil.revrange() in order to raise an
+    exception indicating user error.
+    """
+    try:
+        return scmutil.revrange(repo, specs, localalias)
+    except error.RepoLookupError as e:
+        raise error.InputError(e.args[0], hint=e.hint)
+
+
 _opt2logrevset = {
     b'no_merges': (b'not merge()', None),
     b'only_merges': (b'merge()', None),
@@ -987,7 +999,7 @@ 
 def _initialrevs(repo, wopts):
     """Return the initial set of revisions to be filtered or followed"""
     if wopts.revspec:
-        revs = scmutil.revrange(repo, wopts.revspec)
+        revs = revrange(repo, wopts.revspec)
     elif wopts.follow and repo.dirstate.p1() == repo.nullid:
         revs = smartset.baseset()
     elif wopts.follow:
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -1352,7 +1352,7 @@ 
         ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(dest))
         revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev'))
         if revs:
-            revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
+            revs = [repo[rev].node() for rev in logcmdutil.revrange(repo, revs)]
 
         other = peer(repo, opts, dest)
         try:
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -1097,7 +1097,7 @@ 
         ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(remoteurl))
     else:
         branches = (None, [])
-        remote_filtered_revs = scmutil.revrange(
+        remote_filtered_revs = logcmdutil.revrange(
             unfi, [b"not (::(%s))" % remote_revs]
         )
         remote_filtered_revs = frozenset(remote_filtered_revs)
@@ -1111,7 +1111,7 @@ 
         remote._repo = remote._repo.filtered(b'debug-discovery-remote-filter')
 
     if local_revs:
-        local_filtered_revs = scmutil.revrange(
+        local_filtered_revs = logcmdutil.revrange(
             unfi, [b"not (::(%s))" % local_revs]
         )
         local_filtered_revs = frozenset(local_filtered_revs)
@@ -1149,7 +1149,7 @@ 
         def doit(pushedrevs, remoteheads, remote=remote):
             nodes = None
             if pushedrevs:
-                revs = scmutil.revrange(repo, pushedrevs)
+                revs = logcmdutil.revrange(repo, pushedrevs)
                 nodes = [repo[r].node() for r in revs]
             common, any, hds = setdiscovery.findcommonheads(
                 ui, repo, remote, ancestorsof=nodes, audit=data
@@ -2608,7 +2608,7 @@ 
             l.release()
     else:
         if opts[b'rev']:
-            revs = scmutil.revrange(repo, opts[b'rev'])
+            revs = logcmdutil.revrange(repo, opts[b'rev'])
             nodes = [repo[r].node() for r in revs]
             markers = list(
                 obsutil.getmarkers(
@@ -4024,7 +4024,7 @@ 
     cache = {}
     ctx2str = bytes
     node2str = short
-    for rev in scmutil.revrange(repo, revs):
+    for rev in logcmdutil.revrange(repo, revs):
         ctx = repo[rev]
         ui.write(b'%s\n' % ctx2str(ctx))
         for succsset in obsutil.successorssets(
@@ -4083,7 +4083,7 @@ 
             raise error.RepoError(
                 _(b'there is no Mercurial repository here (.hg not found)')
             )
-        revs = scmutil.revrange(repo, opts['rev'])
+        revs = logcmdutil.revrange(repo, opts['rev'])
 
     props = {}
     for d in opts['define']:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -536,7 +536,7 @@ 
     )
     skiprevs = opts.get(b'skip')
     if skiprevs:
-        skiprevs = scmutil.revrange(repo, skiprevs)
+        skiprevs = logcmdutil.revrange(repo, skiprevs)
 
     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
     for abs in ctx.walk(m):
@@ -1037,7 +1037,7 @@ 
     state = hbisect.load_state(repo)
 
     if rev:
-        nodes = [repo[i].node() for i in scmutil.revrange(repo, rev)]
+        nodes = [repo[i].node() for i in logcmdutil.revrange(repo, rev)]
     else:
         nodes = [repo.lookup(b'.')]
 
@@ -1424,7 +1424,7 @@ 
     revs = opts.get(b'rev')
     selectedbranches = None
     if revs:
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
         getbi = repo.revbranchcache().branchinfo
         selectedbranches = {getbi(r)[0] for r in revs}
 
@@ -1558,7 +1558,7 @@ 
     revs = None
     if b'rev' in opts:
         revstrings = opts[b'rev']
-        revs = scmutil.revrange(repo, revstrings)
+        revs = logcmdutil.revrange(repo, revstrings)
         if revstrings and not revs:
             raise error.InputError(_(b'no commits to bundle'))
 
@@ -1590,7 +1590,7 @@ 
             ui.warn(_(b"ignoring --base because --all was specified\n"))
         base = [nullrev]
     else:
-        base = scmutil.revrange(repo, opts.get(b'base'))
+        base = logcmdutil.revrange(repo, opts.get(b'base'))
     if cgversion not in changegroup.supportedoutgoingversions(repo):
         raise error.Abort(
             _(b"repository does not support bundle version %s") % cgversion
@@ -2753,7 +2753,7 @@ 
             changesets = [b'.']
 
         repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
-        revs = scmutil.revrange(repo, changesets)
+        revs = logcmdutil.revrange(repo, changesets)
 
     if not revs:
         raise error.InputError(_(b"export requires at least one changeset"))
@@ -3170,7 +3170,7 @@ 
             raise error.InputError(_(b'no revisions specified'))
         cmdutil.checkunfinished(repo)
         cmdutil.bailifchanged(repo)
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
 
     skipped = set()
     basectx = None
@@ -3708,7 +3708,7 @@ 
 
     if branchrevs:
         branches = {
-            repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
+            repo[r].branch() for r in logcmdutil.revrange(repo, branchrevs)
         }
         heads = [h for h in heads if h.branch() in branches]
 
@@ -5220,7 +5220,7 @@ 
     revs = list(revs)
     revs.extend(opts[b'rev'])
     if revs:
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
     else:
         # display both parents as the second parent phase can influence
         # the phase of a merge commit
@@ -5735,7 +5735,7 @@ 
 
         try:
             if revs:
-                revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
+                revs = [repo[r].node() for r in logcmdutil.revrange(repo, revs)]
                 if not revs:
                     raise error.InputError(
                         _(b"specified revisions evaluate to an empty set"),
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -987,7 +987,7 @@ 
     with repo.wlock(), repo.lock(), repo.transaction(b'branches'):
         # abort in case of uncommitted merge or dirty wdir
         bailifchanged(repo)
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
         if not revs:
             raise error.InputError(b"empty revision set")
         roots = repo.revs(b'roots(%ld)', revs)
diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -37,7 +37,6 @@ 
     pycompat,
     registrar,
     revset,
-    scmutil,
     smartset,
     state as statemod,
     util,
@@ -845,7 +844,7 @@ 
         if opts.get(b'prune'):
             prune = {
                 source[r].node()
-                for r in scmutil.revrange(source, opts.get(b'prune'))
+                for r in logcmdutil.revrange(source, opts.get(b'prune'))
             }
             matchfn = lambda x: tf(x) and x not in prune
         else:
@@ -853,7 +852,7 @@ 
         merges = pycompat.maplist(source.lookup, opts.get(b'merge', ()))
         revmap = {}
         if revs:
-            for r in scmutil.revrange(source, revs):
+            for r in logcmdutil.revrange(source, revs):
                 revmap[int(r)] = source[r].node()
         elif opts.get(b'all') or not merges:
             if source != repo:
diff --git a/hgext/split.py b/hgext/split.py
--- a/hgext/split.py
+++ b/hgext/split.py
@@ -22,6 +22,7 @@ 
     commands,
     error,
     hg,
+    logcmdutil,
     pycompat,
     registrar,
     revsetlang,
@@ -75,7 +76,7 @@ 
         # If the rebase somehow runs into conflicts, make sure
         # we close the transaction so the user can continue it.
         with util.acceptintervention(tr):
-            revs = scmutil.revrange(repo, revlist or [b'.'])
+            revs = logcmdutil.revrange(repo, revlist or [b'.'])
             if len(revs) > 1:
                 raise error.InputError(_(b'cannot split multiple revisions'))
 
diff --git a/hgext/releasenotes.py b/hgext/releasenotes.py
--- a/hgext/releasenotes.py
+++ b/hgext/releasenotes.py
@@ -24,10 +24,10 @@ 
     cmdutil,
     config,
     error,
+    logcmdutil,
     minirst,
     pycompat,
     registrar,
-    scmutil,
     util,
 )
 from mercurial.utils import (
@@ -676,7 +676,7 @@ 
         return _getadmonitionlist(ui, sections)
 
     rev = opts.get(b'rev')
-    revs = scmutil.revrange(repo, [rev or b'not public()'])
+    revs = logcmdutil.revrange(repo, [rev or b'not public()'])
     if opts.get(b'check'):
         return checkadmonitions(ui, repo, sections.names(), revs)
 
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -35,6 +35,7 @@ 
     dirstateguard,
     error,
     extensions,
+    logcmdutil,
     merge as mergemod,
     mergestate as mergestatemod,
     mergeutil,
@@ -1302,19 +1303,19 @@ 
     dest = None
 
     if revf:
-        rebaseset = scmutil.revrange(repo, revf)
+        rebaseset = logcmdutil.revrange(repo, revf)
         if not rebaseset:
             ui.status(_(b'empty "rev" revision set - nothing to rebase\n'))
             return None
     elif srcf:
-        src = scmutil.revrange(repo, srcf)
+        src = logcmdutil.revrange(repo, srcf)
         if not src:
             ui.status(_(b'empty "source" revision set - nothing to rebase\n'))
             return None
         # `+  (%ld)` to work around `wdir()::` being empty
         rebaseset = repo.revs(b'(%ld):: + (%ld)', src, src)
     else:
-        base = scmutil.revrange(repo, basef or [b'.'])
+        base = logcmdutil.revrange(repo, basef or [b'.'])
         if not base:
             ui.status(
                 _(b'empty "base" revision set - ' b"can't compute rebase set\n")
diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -1354,7 +1354,7 @@ 
     """
     opts = pycompat.byteskwargs(opts)
     revs = list(revs) + opts.get(b'rev', [])
-    revs = scmutil.revrange(repo, revs)
+    revs = logcmdutil.revrange(repo, revs)
     revs.sort()  # ascending order to preserve topological parent/child in phab
 
     if not revs:
@@ -2276,7 +2276,7 @@ 
         if specs:
             raise error.InputError(_(b'cannot specify both DREVSPEC and --rev'))
 
-        drevmap = getdrevmap(repo, scmutil.revrange(repo, [revs]))
+        drevmap = getdrevmap(repo, logcmdutil.revrange(repo, [revs]))
         specs = []
         unknown = []
         for r, d in pycompat.iteritems(drevmap):
diff --git a/hgext/patchbomb.py b/hgext/patchbomb.py
--- a/hgext/patchbomb.py
+++ b/hgext/patchbomb.py
@@ -91,6 +91,7 @@ 
     error,
     formatter,
     hg,
+    logcmdutil,
     mail,
     patch,
     pycompat,
@@ -812,7 +813,7 @@ 
             raise error.Abort(_(b"bookmark '%s' not found") % bookmark)
         revs = scmutil.bookmarkrevs(repo, bookmark)
 
-    revs = scmutil.revrange(repo, revs)
+    revs = logcmdutil.revrange(repo, revs)
     if outgoing:
         revs = _getoutgoing(repo, dest, revs)
     if bundle:
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -1241,7 +1241,7 @@ 
         if opts.get(b'rev'):
             if not self.applied:
                 raise error.Abort(_(b'no patches applied'))
-            revs = scmutil.revrange(repo, opts.get(b'rev'))
+            revs = logcmdutil.revrange(repo, opts.get(b'rev'))
             revs.sort()
             revpatches = self._revpatches(repo, revs)
             realpatches += revpatches
@@ -2417,7 +2417,7 @@ 
                 raise error.Abort(
                     _(b'option "-r" not valid when importing files')
                 )
-            rev = scmutil.revrange(repo, rev)
+            rev = logcmdutil.revrange(repo, rev)
             rev.sort(reverse=True)
         elif not files:
             raise error.Abort(_(b'no files or revisions specified'))
@@ -3878,7 +3878,7 @@ 
         ui.status(_(b'no patches applied\n'))
         return 0
 
-    revs = scmutil.revrange(repo, revrange)
+    revs = logcmdutil.revrange(repo, revrange)
     if repo[b'.'].rev() in revs and repo[None].files():
         ui.warn(_(b'warning: uncommitted changes in the working directory\n'))
     # queue.finish may changes phases but leave the responsibility to lock the
diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -137,6 +137,7 @@ 
     filelog,
     filesetlang,
     localrepo,
+    logcmdutil,
     minifileset,
     pycompat,
     revlog,
@@ -417,7 +418,7 @@ 
 def debuglfsupload(ui, repo, **opts):
     """upload lfs blobs added by the working copy parent or given revisions"""
     revs = opts.get('rev', [])
-    pointers = wrapper.extractpointers(repo, scmutil.revrange(repo, revs))
+    pointers = wrapper.extractpointers(repo, logcmdutil.revrange(repo, revs))
     wrapper.uploadblobs(repo, pointers)
 
 
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1000,7 +1000,7 @@ 
         numcached = 0
         repo.firstpulled = revsprepull  # for pulled() revset expression
         try:
-            for rev in scmutil.revrange(repo, lfrevs):
+            for rev in logcmdutil.revrange(repo, lfrevs):
                 ui.note(_(b'pulling largefiles for revision %d\n') % rev)
                 (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
                 numcached += len(cached)
@@ -1027,7 +1027,7 @@ 
     lfrevs = kwargs.pop('lfrev', None)
     if lfrevs:
         opargs = kwargs.setdefault('opargs', {})
-        opargs[b'lfrevs'] = scmutil.revrange(repo, lfrevs)
+        opargs[b'lfrevs'] = logcmdutil.revrange(repo, lfrevs)
     return orig(ui, repo, *args, **kwargs)
 
 
diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py
--- a/hgext/largefiles/lfcommands.py
+++ b/hgext/largefiles/lfcommands.py
@@ -26,6 +26,7 @@ 
     exthelper,
     hg,
     lock,
+    logcmdutil,
     match as matchmod,
     pycompat,
     scmutil,
@@ -657,7 +658,7 @@ 
     revs = opts.get('rev', [])
     if not revs:
         raise error.Abort(_(b'no revisions specified'))
-    revs = scmutil.revrange(repo, revs)
+    revs = logcmdutil.revrange(repo, revs)
 
     numcached = 0
     for rev in revs:
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -1707,7 +1707,7 @@ 
                 _(b'histedit requires exactly one ancestor revision')
             )
 
-        rr = list(repo.set(b'roots(%ld)', scmutil.revrange(repo, revs)))
+        rr = list(repo.set(b'roots(%ld)', logcmdutil.revrange(repo, revs)))
         if len(rr) != 1:
             raise error.InputError(
                 _(
@@ -1982,7 +1982,7 @@ 
 
     hastags = False
     if revs:
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
         ctxs = [repo[rev] for rev in revs]
         for ctx in ctxs:
             tags = [tag for tag in ctx.tags() if tag != b'tip']
@@ -2205,7 +2205,7 @@ 
             remote = None
         root = findoutgoing(ui, repo, remote, force, opts)
     else:
-        rr = list(repo.set(b'roots(%ld)', scmutil.revrange(repo, revs)))
+        rr = list(repo.set(b'roots(%ld)', logcmdutil.revrange(repo, revs)))
         if len(rr) != 1:
             raise error.InputError(
                 _(
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -144,6 +144,7 @@ 
     context,
     copies,
     error,
+    logcmdutil,
     match as matchmod,
     mdiff,
     merge,
@@ -420,7 +421,7 @@ 
     if opts[b'all']:
         revs = repo.revs(b'(not public() and not obsolete()) or wdir()')
     elif opts[b'source']:
-        source_revs = scmutil.revrange(repo, opts[b'source'])
+        source_revs = logcmdutil.revrange(repo, opts[b'source'])
         revs = set(repo.revs(b'(%ld::) - obsolete()', source_revs))
         if wdirrev in source_revs:
             # `wdir()::` is currently empty, so manually add wdir
@@ -428,7 +429,7 @@ 
         if repo[b'.'].rev() in revs:
             revs.add(wdirrev)
     else:
-        revs = set(scmutil.revrange(repo, opts[b'rev']))
+        revs = set(logcmdutil.revrange(repo, opts[b'rev']))
         if opts.get(b'working_dir'):
             revs.add(wdirrev)
         for rev in revs:
@@ -618,7 +619,7 @@ 
     # The --base flag overrides the usual logic, and we give every revision
     # exactly the set of baserevs that the user specified.
     if opts.get(b'base'):
-        baserevs = set(scmutil.revrange(repo, opts.get(b'base')))
+        baserevs = set(logcmdutil.revrange(repo, opts.get(b'base')))
         if not baserevs:
             baserevs = {nullrev}
         basectxs = {repo[rev] for rev in baserevs}
diff --git a/hgext/fastexport.py b/hgext/fastexport.py
--- a/hgext/fastexport.py
+++ b/hgext/fastexport.py
@@ -15,6 +15,7 @@ 
 from mercurial.utils import stringutil
 from mercurial import (
     error,
+    logcmdutil,
     pycompat,
     registrar,
     scmutil,
@@ -182,7 +183,7 @@ 
     if not revs:
         revs = scmutil.revrange(repo, [b":"])
     else:
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
     if not revs:
         raise error.Abort(_(b"no revisions matched"))
     authorfile = opts.get(b"authormap")
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -36,10 +36,10 @@ 
     exchange,
     hg,
     lock as lockmod,
+    logcmdutil,
     merge as mergemod,
     phases,
     pycompat,
-    scmutil,
     util,
 )
 from mercurial.utils import dateutil
@@ -564,7 +564,7 @@ 
                 )
             nodes = set()
             parents = set()
-            for r in scmutil.revrange(self.repo, [hgrevs]):
+            for r in logcmdutil.revrange(self.repo, [hgrevs]):
                 ctx = self.repo[r]
                 nodes.add(ctx.node())
                 parents.update(p.node() for p in ctx.parents())
diff --git a/hgext/closehead.py b/hgext/closehead.py
--- a/hgext/closehead.py
+++ b/hgext/closehead.py
@@ -15,7 +15,7 @@ 
     error,
     pycompat,
     registrar,
-    scmutil,
+    logcmdutil,
 )
 
 cmdtable = {}
@@ -68,7 +68,7 @@ 
     opts = pycompat.byteskwargs(opts)
 
     revs += tuple(opts.get(b'rev', []))
-    revs = scmutil.revrange(repo, revs)
+    revs = logcmdutil.revrange(repo, revs)
 
     if not revs:
         raise error.Abort(_(b'no revisions specified'))
diff --git a/contrib/synthrepo.py b/contrib/synthrepo.py
--- a/contrib/synthrepo.py
+++ b/contrib/synthrepo.py
@@ -57,10 +57,10 @@ 
     diffutil,
     error,
     hg,
+    logcmdutil,
     patch,
     pycompat,
     registrar,
-    scmutil,
 )
 from mercurial.utils import dateutil
 
@@ -180,7 +180,7 @@ 
 
     # If a mercurial repo is available, also model the commit history.
     if repo:
-        revs = scmutil.revrange(repo, revs)
+        revs = logcmdutil.revrange(repo, revs)
         revs.sort()
 
         progress = ui.makeprogress(