debugcommands: move debugbuilddag
And we drop some now unused imports from commands.py.
--- a/mercurial/commands.py Wed Aug 17 21:07:38 2016 -0700
+++ b/mercurial/commands.py Thu Nov 10 09:45:42 2016 -0800
@@ -35,7 +35,6 @@
changegroup,
cmdutil,
commandserver,
- context,
copies,
dagparser,
dagutil,
@@ -67,7 +66,6 @@
revset,
scmutil,
setdiscovery,
- simplemerge,
sshserver,
sslutil,
streamclone,
@@ -1867,158 +1865,6 @@
with repo.wlock(False):
return cmdutil.copy(ui, repo, pats, opts)
-@command('debugbuilddag',
- [('m', 'mergeable-file', None, _('add single file mergeable changes')),
- ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
- ('n', 'new-file', None, _('add new file at each rev'))],
- _('[OPTION]... [TEXT]'))
-def debugbuilddag(ui, repo, text=None,
- mergeable_file=False,
- overwritten_file=False,
- new_file=False):
- """builds a repo with a given DAG from scratch in the current empty repo
-
- The description of the DAG is read from stdin if not given on the
- command line.
-
- Elements:
-
- - "+n" is a linear run of n nodes based on the current default parent
- - "." is a single node based on the current default parent
- - "$" resets the default parent to null (implied at the start);
- otherwise the default parent is always the last node created
- - "<p" sets the default parent to the backref p
- - "*p" is a fork at parent p, which is a backref
- - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
- - "/p2" is a merge of the preceding node and p2
- - ":tag" defines a local tag for the preceding node
- - "@branch" sets the named branch for subsequent nodes
- - "#...\\n" is a comment up to the end of the line
-
- Whitespace between the above elements is ignored.
-
- A backref is either
-
- - a number n, which references the node curr-n, where curr is the current
- node, or
- - the name of a local tag you placed earlier using ":tag", or
- - empty to denote the default parent.
-
- All string valued-elements are either strictly alphanumeric, or must
- be enclosed in double quotes ("..."), with "\\" as escape character.
- """
-
- if text is None:
- ui.status(_("reading DAG from stdin\n"))
- text = ui.fin.read()
-
- cl = repo.changelog
- if len(cl) > 0:
- raise error.Abort(_('repository is not empty'))
-
- # determine number of revs in DAG
- total = 0
- for type, data in dagparser.parsedag(text):
- if type == 'n':
- total += 1
-
- if mergeable_file:
- linesperrev = 2
- # make a file with k lines per rev
- initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
- initialmergedlines.append("")
-
- tags = []
-
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction("builddag")
-
- at = -1
- atbranch = 'default'
- nodeids = []
- id = 0
- ui.progress(_('building'), id, unit=_('revisions'), total=total)
- for type, data in dagparser.parsedag(text):
- if type == 'n':
- ui.note(('node %s\n' % str(data)))
- id, ps = data
-
- files = []
- fctxs = {}
-
- p2 = None
- if mergeable_file:
- fn = "mf"
- p1 = repo[ps[0]]
- if len(ps) > 1:
- p2 = repo[ps[1]]
- pa = p1.ancestor(p2)
- base, local, other = [x[fn].data() for x in (pa, p1,
- p2)]
- m3 = simplemerge.Merge3Text(base, local, other)
- ml = [l.strip() for l in m3.merge_lines()]
- ml.append("")
- elif at > 0:
- ml = p1[fn].data().split("\n")
- else:
- ml = initialmergedlines
- ml[id * linesperrev] += " r%i" % id
- mergedtext = "\n".join(ml)
- files.append(fn)
- fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
-
- if overwritten_file:
- fn = "of"
- files.append(fn)
- fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
-
- if new_file:
- fn = "nf%i" % id
- files.append(fn)
- fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
- if len(ps) > 1:
- if not p2:
- p2 = repo[ps[1]]
- for fn in p2:
- if fn.startswith("nf"):
- files.append(fn)
- fctxs[fn] = p2[fn]
-
- def fctxfn(repo, cx, path):
- return fctxs.get(path)
-
- if len(ps) == 0 or ps[0] < 0:
- pars = [None, None]
- elif len(ps) == 1:
- pars = [nodeids[ps[0]], None]
- else:
- pars = [nodeids[p] for p in ps]
- cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
- date=(id, 0),
- user="debugbuilddag",
- extra={'branch': atbranch})
- nodeid = repo.commitctx(cx)
- nodeids.append(nodeid)
- at = id
- elif type == 'l':
- id, name = data
- ui.note(('tag %s\n' % name))
- tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
- elif type == 'a':
- ui.note(('branch %s\n' % data))
- atbranch = data
- ui.progress(_('building'), id, unit=_('revisions'), total=total)
- tr.close()
-
- if tags:
- repo.vfs.write("localtags", "".join(tags))
- finally:
- ui.progress(_('building'), None)
- release(tr, lock, wlock)
-
@command('debugbundle',
[('a', 'all', None, _('show all details')),
('', 'spec', None, _('print the bundlespec of the bundle'))],
--- a/mercurial/debugcommands.py Wed Aug 17 21:07:38 2016 -0700
+++ b/mercurial/debugcommands.py Thu Nov 10 09:45:42 2016 -0800
@@ -10,14 +10,23 @@
import os
from .i18n import _
+from .node import (
+ hex,
+)
from . import (
cmdutil,
commands,
+ context,
+ dagparser,
error,
+ lock as lockmod,
revlog,
scmutil,
+ simplemerge,
)
+release = lockmod.release
+
# We reuse the command table from commands because it is easier than
# teaching dispatch about multiple tables.
command = cmdutil.command(commands.table)
@@ -40,3 +49,155 @@
raise error.Abort(_('either two or three arguments required'))
a = r.ancestor(lookup(rev1), lookup(rev2))
ui.write('%d:%s\n' % (r.rev(a), hex(a)))
+
+@command('debugbuilddag',
+ [('m', 'mergeable-file', None, _('add single file mergeable changes')),
+ ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
+ ('n', 'new-file', None, _('add new file at each rev'))],
+ _('[OPTION]... [TEXT]'))
+def debugbuilddag(ui, repo, text=None,
+ mergeable_file=False,
+ overwritten_file=False,
+ new_file=False):
+ """builds a repo with a given DAG from scratch in the current empty repo
+
+ The description of the DAG is read from stdin if not given on the
+ command line.
+
+ Elements:
+
+ - "+n" is a linear run of n nodes based on the current default parent
+ - "." is a single node based on the current default parent
+ - "$" resets the default parent to null (implied at the start);
+ otherwise the default parent is always the last node created
+ - "<p" sets the default parent to the backref p
+ - "*p" is a fork at parent p, which is a backref
+ - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
+ - "/p2" is a merge of the preceding node and p2
+ - ":tag" defines a local tag for the preceding node
+ - "@branch" sets the named branch for subsequent nodes
+ - "#...\\n" is a comment up to the end of the line
+
+ Whitespace between the above elements is ignored.
+
+ A backref is either
+
+ - a number n, which references the node curr-n, where curr is the current
+ node, or
+ - the name of a local tag you placed earlier using ":tag", or
+ - empty to denote the default parent.
+
+ All string valued-elements are either strictly alphanumeric, or must
+ be enclosed in double quotes ("..."), with "\\" as escape character.
+ """
+
+ if text is None:
+ ui.status(_("reading DAG from stdin\n"))
+ text = ui.fin.read()
+
+ cl = repo.changelog
+ if len(cl) > 0:
+ raise error.Abort(_('repository is not empty'))
+
+ # determine number of revs in DAG
+ total = 0
+ for type, data in dagparser.parsedag(text):
+ if type == 'n':
+ total += 1
+
+ if mergeable_file:
+ linesperrev = 2
+ # make a file with k lines per rev
+ initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
+ initialmergedlines.append("")
+
+ tags = []
+
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction("builddag")
+
+ at = -1
+ atbranch = 'default'
+ nodeids = []
+ id = 0
+ ui.progress(_('building'), id, unit=_('revisions'), total=total)
+ for type, data in dagparser.parsedag(text):
+ if type == 'n':
+ ui.note(('node %s\n' % str(data)))
+ id, ps = data
+
+ files = []
+ fctxs = {}
+
+ p2 = None
+ if mergeable_file:
+ fn = "mf"
+ p1 = repo[ps[0]]
+ if len(ps) > 1:
+ p2 = repo[ps[1]]
+ pa = p1.ancestor(p2)
+ base, local, other = [x[fn].data() for x in (pa, p1,
+ p2)]
+ m3 = simplemerge.Merge3Text(base, local, other)
+ ml = [l.strip() for l in m3.merge_lines()]
+ ml.append("")
+ elif at > 0:
+ ml = p1[fn].data().split("\n")
+ else:
+ ml = initialmergedlines
+ ml[id * linesperrev] += " r%i" % id
+ mergedtext = "\n".join(ml)
+ files.append(fn)
+ fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
+
+ if overwritten_file:
+ fn = "of"
+ files.append(fn)
+ fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
+
+ if new_file:
+ fn = "nf%i" % id
+ files.append(fn)
+ fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
+ if len(ps) > 1:
+ if not p2:
+ p2 = repo[ps[1]]
+ for fn in p2:
+ if fn.startswith("nf"):
+ files.append(fn)
+ fctxs[fn] = p2[fn]
+
+ def fctxfn(repo, cx, path):
+ return fctxs.get(path)
+
+ if len(ps) == 0 or ps[0] < 0:
+ pars = [None, None]
+ elif len(ps) == 1:
+ pars = [nodeids[ps[0]], None]
+ else:
+ pars = [nodeids[p] for p in ps]
+ cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
+ date=(id, 0),
+ user="debugbuilddag",
+ extra={'branch': atbranch})
+ nodeid = repo.commitctx(cx)
+ nodeids.append(nodeid)
+ at = id
+ elif type == 'l':
+ id, name = data
+ ui.note(('tag %s\n' % name))
+ tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
+ elif type == 'a':
+ ui.note(('branch %s\n' % data))
+ atbranch = data
+ ui.progress(_('building'), id, unit=_('revisions'), total=total)
+ tr.close()
+
+ if tags:
+ repo.vfs.write("localtags", "".join(tags))
+ finally:
+ ui.progress(_('building'), None)
+ release(tr, lock, wlock)
--- a/tests/test-ancestor.py Wed Aug 17 21:07:38 2016 -0700
+++ b/tests/test-ancestor.py Thu Nov 10 09:45:42 2016 -0800
@@ -11,7 +11,7 @@
from mercurial.node import nullrev
from mercurial import (
ancestor,
- commands,
+ debugcommands,
hg,
ui as uimod,
util,
@@ -226,7 +226,7 @@
# C version not available
return
- commands.debugbuilddag(u, repo, dag)
+ debugcommands.debugbuilddag(u, repo, dag)
# Compare the results of the Python and C versions. This does not
# include choosing a winner when more than one gca exists -- we make
# sure both return exactly the same set of gcas.