scmutil: move revsingle/pair/range from cmdutil
This allows users at levels below the command layer to avoid import loops.
--- a/hgext/extdiff.py Fri May 13 12:57:27 2011 -0500
+++ b/hgext/extdiff.py Fri May 13 14:06:28 2011 -0500
@@ -123,10 +123,10 @@
msg = _('cannot specify --rev and --change at the same time')
raise util.Abort(msg)
elif change:
- node2 = cmdutil.revsingle(repo, change, None).node()
+ node2 = scmutil.revsingle(repo, change, None).node()
node1a, node1b = repo.changelog.parents(node2)
else:
- node1a, node2 = cmdutil.revpair(repo, revs)
+ node1a, node2 = scmutil.revpair(repo, revs)
if not revs:
node1b = repo.dirstate.p2()
else:
--- a/hgext/graphlog.py Fri May 13 12:57:27 2011 -0500
+++ b/hgext/graphlog.py Fri May 13 14:06:28 2011 -0500
@@ -12,11 +12,11 @@
revision graph is also shown.
'''
-from mercurial.cmdutil import revrange, show_changeset
+from mercurial.cmdutil import show_changeset
from mercurial.commands import templateopts
from mercurial.i18n import _
from mercurial.node import nullrev
-from mercurial import cmdutil, commands, extensions
+from mercurial import cmdutil, commands, extensions, scmutil
from mercurial import hg, util, graphmod
cmdtable = {}
@@ -227,7 +227,7 @@
def get_revs(repo, rev_opt):
if rev_opt:
- revs = revrange(repo, rev_opt)
+ revs = scmutil.revrange(repo, rev_opt)
if len(revs) == 0:
return (nullrev, nullrev)
return (max(revs), min(revs))
@@ -324,7 +324,7 @@
check_unsupported_flags(pats, opts)
- revs = sorted(revrange(repo, [revset(pats, opts)]), reverse=1)
+ revs = sorted(scmutil.revrange(repo, [revset(pats, opts)]), reverse=1)
limit = cmdutil.loglimit(opts)
if limit is not None:
revs = revs[:limit]
--- a/hgext/mq.py Fri May 13 12:57:27 2011 -0500
+++ b/hgext/mq.py Fri May 13 14:06:28 2011 -0500
@@ -46,7 +46,7 @@
from mercurial.node import bin, hex, short, nullid, nullrev
from mercurial.lock import release
from mercurial import commands, cmdutil, hg, scmutil, util, revset
-from mercurial import repair, extensions, url, error
+from mercurial import repair, extensions, url, error, scmutil
from mercurial import patch as patchmod
import os, sys, re, errno, shutil
@@ -815,7 +815,7 @@
if opts.get('rev'):
if not self.applied:
raise util.Abort(_('no patches applied'))
- revs = cmdutil.revrange(repo, opts.get('rev'))
+ revs = scmutil.revrange(repo, opts.get('rev'))
if len(revs) > 1 and revs[0] > revs[1]:
revs.reverse()
revpatches = self._revpatches(repo, revs)
@@ -1748,7 +1748,7 @@
if files:
raise util.Abort(_('option "-r" not valid when importing '
'files'))
- rev = cmdutil.revrange(repo, rev)
+ rev = scmutil.revrange(repo, rev)
rev.sort(reverse=True)
if (len(files) > 1 or len(rev) > 1) and patchname:
raise util.Abort(_('option "-n" not valid when importing multiple '
@@ -2736,7 +2736,7 @@
backup = 'none'
cl = repo.changelog
- revs = set(cmdutil.revrange(repo, revs))
+ revs = set(scmutil.revrange(repo, revs))
if not revs:
raise util.Abort(_('empty revision set'))
@@ -2928,7 +2928,7 @@
ui.status(_('no patches applied\n'))
return 0
- revs = cmdutil.revrange(repo, revrange)
+ revs = scmutil.revrange(repo, revrange)
q.finish(repo, revs)
q.save_dirty()
return 0
--- a/hgext/patchbomb.py Fri May 13 12:57:27 2011 -0500
+++ b/hgext/patchbomb.py Fri May 13 14:06:28 2011 -0500
@@ -49,6 +49,7 @@
import email.MIMEMultipart, email.MIMEBase
import email.Utils, email.Encoders, email.Generator
from mercurial import cmdutil, commands, hg, mail, patch, util, discovery
+from mercurial import scmutil
from mercurial.i18n import _
from mercurial.node import bin
@@ -286,7 +287,7 @@
return [str(repo.changelog.rev(r)) for r in o]
def getpatches(revs):
- for r in cmdutil.revrange(repo, revs):
+ for r in scmutil.revrange(repo, revs):
output = cStringIO.StringIO()
cmdutil.export(repo, [r], fp=output,
opts=patch.diffopts(ui, opts))
--- a/hgext/transplant.py Fri May 13 12:57:27 2011 -0500
+++ b/hgext/transplant.py Fri May 13 14:06:28 2011 -0500
@@ -15,8 +15,8 @@
from mercurial.i18n import _
import os, tempfile
-from mercurial import bundlerepo, cmdutil, hg, merge, match
-from mercurial import patch, revlog, scmutil, util, error
+from mercurial import bundlerepo, hg, merge, match
+from mercurial import patch, revlog, scmutil, util, error, cmdutil
from mercurial import revset, templatekw
cmdtable = {}
@@ -578,14 +578,14 @@
tf = tp.transplantfilter(repo, source, p1)
if opts.get('prune'):
prune = [source.lookup(r)
- for r in cmdutil.revrange(source, opts.get('prune'))]
+ for r in scmutil.revrange(source, opts.get('prune'))]
matchfn = lambda x: tf(x) and x not in prune
else:
matchfn = tf
merges = map(source.lookup, opts.get('merge', ()))
revmap = {}
if revs:
- for r in cmdutil.revrange(source, revs):
+ for r in scmutil.revrange(source, revs):
revmap[int(r)] = source.lookup(r)
elif opts.get('all') or not merges:
if source != repo:
--- a/mercurial/cmdutil.py Fri May 13 12:57:27 2011 -0500
+++ b/mercurial/cmdutil.py Fri May 13 14:06:28 2011 -0500
@@ -10,7 +10,7 @@
import os, sys, errno, re, tempfile
import util, scmutil, templater, patch, error, templatekw, wdutil
import match as matchmod
-import revset, subrepo
+import subrepo
expandpats = wdutil.expandpats
match = wdutil.match
@@ -19,8 +19,6 @@
addremove = wdutil.addremove
dirstatecopy = wdutil.dirstatecopy
-revrangesep = ':'
-
def parsealiases(cmd):
return cmd.lstrip("^").split("|")
@@ -118,77 +116,6 @@
limit = None
return limit
-def revsingle(repo, revspec, default='.'):
- if not revspec:
- return repo[default]
-
- l = revrange(repo, [revspec])
- if len(l) < 1:
- raise util.Abort(_('empty revision set'))
- return repo[l[-1]]
-
-def revpair(repo, revs):
- if not revs:
- return repo.dirstate.p1(), None
-
- l = revrange(repo, revs)
-
- if len(l) == 0:
- return repo.dirstate.p1(), None
-
- if len(l) == 1:
- return repo.lookup(l[0]), None
-
- return repo.lookup(l[0]), repo.lookup(l[-1])
-
-def revrange(repo, revs):
- """Yield revision as strings from a list of revision specifications."""
-
- def revfix(repo, val, defval):
- if not val and val != 0 and defval is not None:
- return defval
- return repo.changelog.rev(repo.lookup(val))
-
- seen, l = set(), []
- for spec in revs:
- # attempt to parse old-style ranges first to deal with
- # things like old-tag which contain query metacharacters
- try:
- if isinstance(spec, int):
- seen.add(spec)
- l.append(spec)
- continue
-
- if revrangesep in spec:
- start, end = spec.split(revrangesep, 1)
- start = revfix(repo, start, 0)
- end = revfix(repo, end, len(repo) - 1)
- step = start > end and -1 or 1
- for rev in xrange(start, end + step, step):
- if rev in seen:
- continue
- seen.add(rev)
- l.append(rev)
- continue
- elif spec and spec in repo: # single unquoted rev
- rev = revfix(repo, spec, None)
- if rev in seen:
- continue
- seen.add(rev)
- l.append(rev)
- continue
- except error.RepoLookupError:
- pass
-
- # fall through to new-style queries if old-style fails
- m = revset.match(repo.ui, spec)
- for r in m(repo, range(len(repo))):
- if r not in seen:
- l.append(r)
- seen.update(l)
-
- return l
-
def makefilename(repo, pat, node,
total=None, seqno=None, revwidth=None, pathname=None):
node_expander = {
@@ -974,7 +901,7 @@
defrange = '%s:0' % repo['.'].rev()
else:
defrange = '-1:0'
- revs = revrange(repo, opts['rev'] or [defrange])
+ revs = scmutil.revrange(repo, opts['rev'] or [defrange])
if not revs:
return []
wanted = set()
--- a/mercurial/commands.py Fri May 13 12:57:27 2011 -0500
+++ b/mercurial/commands.py Fri May 13 14:06:28 2011 -0500
@@ -261,7 +261,7 @@
def bad(x, y):
raise util.Abort("%s: %s" % (x, y))
- ctx = cmdutil.revsingle(repo, opts.get('rev'))
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
m = cmdutil.match(repo, pats, opts)
m.bad = bad
follow = not opts.get('no_follow')
@@ -322,7 +322,7 @@
Returns 0 on success.
'''
- ctx = cmdutil.revsingle(repo, opts.get('rev'))
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
if not ctx:
raise util.Abort(_('no working directory: please specify a revision'))
node = ctx.node()
@@ -390,7 +390,7 @@
opts['date'] = util.parsedate(date)
cmdutil.bailifchanged(repo)
- node = cmdutil.revsingle(repo, rev).node()
+ node = scmutil.revsingle(repo, rev).node()
op1, op2 = repo.dirstate.parents()
a = repo.changelog.ancestor(op1, node)
@@ -573,7 +573,7 @@
raise util.Abort(_("%s killed") % command)
else:
transition = "bad"
- ctx = cmdutil.revsingle(repo, rev)
+ ctx = scmutil.revsingle(repo, rev)
rev = None # clear for future iterations
state[transition].append(ctx.node())
ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
@@ -591,7 +591,7 @@
# update state
if rev:
- nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
+ nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
else:
nodes = [repo.lookup('.')]
@@ -876,12 +876,12 @@
"""
revs = None
if 'rev' in opts:
- revs = cmdutil.revrange(repo, opts['rev'])
+ revs = scmutil.revrange(repo, opts['rev'])
if opts.get('all'):
base = ['null']
else:
- base = cmdutil.revrange(repo, opts.get('base'))
+ base = scmutil.revrange(repo, opts.get('base'))
if base:
if dest:
raise util.Abort(_("--base is incompatible with specifying "
@@ -935,7 +935,7 @@
Returns 0 on success.
"""
- ctx = cmdutil.revsingle(repo, opts.get('rev'))
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
err = 1
m = cmdutil.match(repo, (file1,) + pats, opts)
for abs in ctx.walk(m):
@@ -1831,7 +1831,7 @@
_('[-r REV] [REV]'))
def debugrebuildstate(ui, repo, rev="tip"):
"""rebuild the dirstate as it would look like for the given revision"""
- ctx = cmdutil.revsingle(repo, rev)
+ ctx = scmutil.revsingle(repo, rev)
wlock = repo.wlock()
try:
repo.dirstate.rebuild(ctx.node(), ctx.manifest())
@@ -1844,7 +1844,7 @@
def debugrename(ui, repo, file1, *pats, **opts):
"""dump rename information"""
- ctx = cmdutil.revsingle(repo, opts.get('rev'))
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
m = cmdutil.match(repo, (file1,) + pats, opts)
for abs in ctx.walk(m):
fctx = ctx[abs]
@@ -2018,8 +2018,8 @@
Returns 0 on success.
"""
- r1 = cmdutil.revsingle(repo, rev1).node()
- r2 = cmdutil.revsingle(repo, rev2, 'null').node()
+ r1 = scmutil.revsingle(repo, rev1).node()
+ r2 = scmutil.revsingle(repo, rev2, 'null').node()
wlock = repo.wlock()
try:
@@ -2064,7 +2064,7 @@
_('revision to check'), _('REV'))],
_('[-r REV] [REV]'))
def debugsub(ui, repo, rev=None):
- ctx = cmdutil.revsingle(repo, rev, None)
+ ctx = scmutil.revsingle(repo, rev, None)
for k, v in sorted(ctx.substate.items()):
ui.write('path %s\n' % k)
ui.write(' source %s\n' % v[0])
@@ -2150,10 +2150,10 @@
msg = _('cannot specify --rev and --change at the same time')
raise util.Abort(msg)
elif change:
- node2 = cmdutil.revsingle(repo, change, None).node()
+ node2 = scmutil.revsingle(repo, change, None).node()
node1 = repo[node2].p1().node()
else:
- node1, node2 = cmdutil.revpair(repo, revs)
+ node1, node2 = scmutil.revpair(repo, revs)
if reverse:
node1, node2 = node2, node1
@@ -2211,7 +2211,7 @@
changesets += tuple(opts.get('rev', []))
if not changesets:
raise util.Abort(_("export requires at least one changeset"))
- revs = cmdutil.revrange(repo, changesets)
+ revs = scmutil.revrange(repo, changesets)
if len(revs) > 1:
ui.note(_('exporting patches:\n'))
else:
@@ -2501,7 +2501,7 @@
start = None
if 'rev' in opts:
- start = cmdutil.revsingle(repo, opts['rev'], None).node()
+ start = scmutil.revsingle(repo, opts['rev'], None).node()
if opts.get('topo'):
heads = [repo[h] for h in repo.heads(start)]
@@ -2944,7 +2944,7 @@
output.append("%s%s" %
('+'.join([str(p.rev()) for p in parents]), changed))
else:
- ctx = cmdutil.revsingle(repo, rev)
+ ctx = scmutil.revsingle(repo, rev)
if default or id:
output = [hexfunc(ctx.node())]
if num:
@@ -3235,7 +3235,7 @@
Returns 0 if a match is found, 1 otherwise.
"""
end = opts.get('print0') and '\0' or '\n'
- rev = cmdutil.revsingle(repo, opts.get('rev'), None).node()
+ rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
ret = 1
m = cmdutil.match(repo, pats, opts, default='relglob')
@@ -3312,7 +3312,7 @@
endrev = None
if opts.get('copies') and opts.get('rev'):
- endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
+ endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
df = False
if opts["date"]:
@@ -3395,7 +3395,7 @@
node = rev
decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
- ctx = cmdutil.revsingle(repo, node)
+ ctx = scmutil.revsingle(repo, node)
for f in ctx:
if ui.debugflag:
ui.write("%40s " % hex(ctx.manifest()[f]))
@@ -3471,7 +3471,7 @@
"explicit revision"))
node = parent == bheads[0] and bheads[-1] or bheads[0]
else:
- node = cmdutil.revsingle(repo, node).node()
+ node = scmutil.revsingle(repo, node).node()
if opts.get('preview'):
# find nodes that are ancestors of p2 but not of p1
@@ -3543,7 +3543,7 @@
Returns 0 on success.
"""
- ctx = cmdutil.revsingle(repo, opts.get('rev'), None)
+ ctx = scmutil.revsingle(repo, opts.get('rev'), None)
if file_:
m = cmdutil.match(repo, (file_,), opts)
@@ -4074,7 +4074,7 @@
raise util.Abort(_('no files or directories specified; '
'use --all to revert the whole repo'))
- ctx = cmdutil.revsingle(repo, opts.get('rev'))
+ ctx = scmutil.revsingle(repo, opts.get('rev'))
node = ctx.node()
mf = ctx.manifest()
if node == parent:
@@ -4519,7 +4519,7 @@
node2 = repo.lookup(change)
node1 = repo[node2].p1().node()
else:
- node1, node2 = cmdutil.revpair(repo, revs)
+ node1, node2 = scmutil.revpair(repo, revs)
cwd = (pats and repo.getcwd()) or ''
end = opts.get('print0') and '\0' or '\n'
@@ -4810,7 +4810,7 @@
bheads = repo.branchheads()
if not opts.get('force') and bheads and p1 not in bheads:
raise util.Abort(_('not at a branch head (use -f to force)'))
- r = cmdutil.revsingle(repo, rev_).node()
+ r = scmutil.revsingle(repo, rev_).node()
if not message:
# we don't translate commit messages
@@ -4961,7 +4961,7 @@
# if we defined a bookmark, we have to remember the original bookmark name
brev = rev
- rev = cmdutil.revsingle(repo, rev, rev).rev()
+ rev = scmutil.revsingle(repo, rev, rev).rev()
if check and clean:
raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
--- a/mercurial/scmutil.py Fri May 13 12:57:27 2011 -0500
+++ b/mercurial/scmutil.py Fri May 13 14:06:28 2011 -0500
@@ -6,7 +6,7 @@
# GNU General Public License version 2 or any later version.
from i18n import _
-import util, error, osutil
+import util, error, osutil, revset
import os, errno, stat, sys
def checkfilename(f):
@@ -463,3 +463,76 @@
path.append(os.path.join(userprofile, 'mercurial.ini'))
path.append(os.path.join(userprofile, '.hgrc'))
return path
+
+def revsingle(repo, revspec, default='.'):
+ if not revspec:
+ return repo[default]
+
+ l = revrange(repo, [revspec])
+ if len(l) < 1:
+ raise util.Abort(_('empty revision set'))
+ return repo[l[-1]]
+
+def revpair(repo, revs):
+ if not revs:
+ return repo.dirstate.p1(), None
+
+ l = revrange(repo, revs)
+
+ if len(l) == 0:
+ return repo.dirstate.p1(), None
+
+ if len(l) == 1:
+ return repo.lookup(l[0]), None
+
+ return repo.lookup(l[0]), repo.lookup(l[-1])
+
+_revrangesep = ':'
+
+def revrange(repo, revs):
+ """Yield revision as strings from a list of revision specifications."""
+
+ def revfix(repo, val, defval):
+ if not val and val != 0 and defval is not None:
+ return defval
+ return repo.changelog.rev(repo.lookup(val))
+
+ seen, l = set(), []
+ for spec in revs:
+ # attempt to parse old-style ranges first to deal with
+ # things like old-tag which contain query metacharacters
+ try:
+ if isinstance(spec, int):
+ seen.add(spec)
+ l.append(spec)
+ continue
+
+ if _revrangesep in spec:
+ start, end = spec.split(_revrangesep, 1)
+ start = revfix(repo, start, 0)
+ end = revfix(repo, end, len(repo) - 1)
+ step = start > end and -1 or 1
+ for rev in xrange(start, end + step, step):
+ if rev in seen:
+ continue
+ seen.add(rev)
+ l.append(rev)
+ continue
+ elif spec and spec in repo: # single unquoted rev
+ rev = revfix(repo, spec, None)
+ if rev in seen:
+ continue
+ seen.add(rev)
+ l.append(rev)
+ continue
+ except error.RepoLookupError:
+ pass
+
+ # fall through to new-style queries if old-style fails
+ m = revset.match(repo.ui, spec)
+ for r in m(repo, range(len(repo))):
+ if r not in seen:
+ l.append(r)
+ seen.update(l)
+
+ return l
--- a/tests/autodiff.py Fri May 13 12:57:27 2011 -0500
+++ b/tests/autodiff.py Fri May 13 14:06:28 2011 -0500
@@ -1,7 +1,7 @@
# Extension dedicated to test patch.diff() upgrade modes
#
#
-from mercurial import cmdutil, patch, util
+from mercurial import cmdutil, scmutil, patch, util
def autodiff(ui, repo, *pats, **opts):
diffopts = patch.diffopts(ui, opts)
@@ -28,7 +28,7 @@
else:
raise util.Abort('--git must be yes, no or auto')
- node1, node2 = cmdutil.revpair(repo, [])
+ node1, node2 = scmutil.revpair(repo, [])
m = cmdutil.match(repo, pats, opts)
it = patch.diff(repo, node1, node2, match=m, opts=diffopts,
losedatafn=losedatafn)