[PATCH] debugbuilddag: build a changelog dag from a concise description
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Mon Feb 8 15:48:44 CST 2010
# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1265665698 -3600
debugbuilddag: build a changelog dag from a concise description
Useful in tests to quickly build a complex DAG in an empty repo.
Can rewrite the same file or a new file at each revision.
Handles local tags and named branches.
Can run shell commands during DAG buildup.
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -743,6 +743,84 @@
a = r.ancestor(lookup(rev1), lookup(rev2))
ui.write("%d:%s\n" % (r.rev(a), hex(a)))
+def debugbuilddag(ui, repo, text, filename='f', append=False):
+ """builds a repo with a given dag from scratch in the current empty repo
+
+ 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, where p is a backref
+ - "*p1/p2" is a merge of parents p1..pn, where the pi 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
+ - "!command" runs the command using your shell
+ - "!!my command\\n" is like "!", but to the end of the line
+ - "#...\\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 len(repo.changelog) > 0:
+ raise Exception(_('repository not empty'))
+
+ # we don't want to fail
+ os.environ['HGMERGE'] = 'internal:local'
+
+ fmode = append and 'a' or 'w'
+ at = -1
+ atbranch = 'default'
+ for type, data in dagparser.dagparse(text):
+ if type == 'n':
+ ui.status('node %s\n' % format(data))
+ id, ps = data
+ p1 = ps[0]
+ if p1 != at:
+ update(ui, repo, node=p1, clean=True)
+ at = p1
+ if repo.dirstate.branch() != atbranch:
+ branch(ui, repo, atbranch, force=True)
+ if len(ps) > 1:
+ p2 = ps[1]
+ merge(ui, repo, node=p2)
+ if '%' in filename:
+ fn = filename % id
+ else:
+ fn = filename
+ f = open(fn, fmode)
+ try:
+ f.write("rev%i\n" % id)
+ finally:
+ f.close()
+ commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
+ at = id
+ elif type == 'l':
+ id, name = data
+ ui.status('tag %s\n' % name)
+ tag(ui, repo, name, local=True)
+ elif type == 'a':
+ ui.status('branch %s\n' % data)
+ atbranch = data
+ elif type in 'cC':
+ r = util.system(data, cwd=repo.root)
+ if r:
+ desc, r = util.explain_exit(r)
+ raise util.Abort(_('%s command %s') % (data, desc))
+
def debugcommands(ui, cmd='', *args):
for cmd, vals in sorted(table.iteritems()):
cmd = cmd.split('|')[0].strip('^')
@@ -3545,6 +3623,12 @@
] + walkopts + dryrunopts,
_('[OPTION]... [SOURCE]... DEST')),
"debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
+ "debugbuilddag":
+ (debugbuilddag,
+ [('f', 'filename', 'f', _('name of updated file (can include %i for rev)')),
+ ('a', 'append', None, _('append to file instead of overwriting')),
+ ],
+ _('[OPTION]... TEXT')),
"debugcheckstate": (debugcheckstate, [], ''),
"debugcommands": (debugcommands, [], _('[COMMAND]')),
"debugcomplete":
diff --git a/tests/test-debugbuilddag b/tests/test-debugbuilddag
new file mode 100755
--- /dev/null
+++ b/tests/test-debugbuilddag
@@ -0,0 +1,59 @@
+#! /bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "graphlog=" >> $HGRCPATH
+
+
+
+echo ---- default
+
+rm -rf repo
+hg init repo
+cd repo
+hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -q
+hg debugdag -t -b
+hg glog --template '{rev}: {desc} [{branches}] @ {date}\n'
+hg glog --template '{rev}: {desc} [{branches}]\n' f
+hg tags -v
+hg cat f
+cd ..
+
+echo ---- new files
+
+rm -rf repo
+hg init repo
+cd repo
+hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -f 'f%i' -q
+hg debugdag -t -b
+hg glog --template '{rev}: {desc} [{branches}]\n'
+echo manifest r4
+hg manifest -r4
+echo manifest r8
+hg manifest -r8
+echo manifest tip
+hg manifest
+cd ..
+
+echo ---- append
+
+rm -rf repo
+hg init repo
+cd repo
+hg debugbuilddag '+2:f +3:p2 @temp <f+4 @default /p2 +2' -a -q
+hg debugdag -t -b
+hg glog --template '{rev}: {desc} [{branches}]\n'
+hg glog --template '{rev}: {desc} [{branches}]\n' f
+hg cat f
+cd ..
+
+echo ---- command
+
+rm -rf repo
+hg init repo
+cd repo
+hg debugbuilddag '+2 !"touch X" +2' -a -q
+hg debugdag -t -b
+hg glog --template '{rev}: {desc} [{branches}]\n'
+hg glog --template '{rev}: {desc} [{branches}]\n' X
+cd ..
+
diff --git a/tests/test-debugbuilddag.out b/tests/test-debugbuilddag.out
new file mode 100644
--- /dev/null
+++ b/tests/test-debugbuilddag.out
@@ -0,0 +1,186 @@
+---- default
++2 :f
++3 :p2
+ at temp *f +3
+ at default */p2 +2 :tip
+@ 11: r11 [] @ 11.00
+|
+o 10: r10 [] @ 10.00
+|
+o 9: r9 [] @ 9.00
+|\
+| o 8: r8 [temp] @ 8.00
+| |
+| o 7: r7 [temp] @ 7.00
+| |
+| o 6: r6 [temp] @ 6.00
+| |
+| o 5: r5 [temp] @ 5.00
+| |
+o | 4: r4 [] @ 4.00
+| |
+o | 3: r3 [] @ 3.00
+| |
+o | 2: r2 [] @ 2.00
+|/
+o 1: r1 [] @ 1.00
+|
+o 0: r0 [] @ 0.00
+
+@ 11: r11 []
+|
+o 10: r10 []
+|
+o 9: r9 []
+|\
+| o 8: r8 [temp]
+| |
+| o 7: r7 [temp]
+| |
+| o 6: r6 [temp]
+| |
+| o 5: r5 [temp]
+| |
+o | 4: r4 []
+| |
+o | 3: r3 []
+| |
+o | 2: r2 []
+|/
+o 1: r1 []
+|
+o 0: r0 []
+
+tip 11:aa002853f7b7
+p2 4:4aaea2ce765e local
+f 1:186275cc9a26 local
+rev11
+---- new files
++2 :f
++3 :p2
+ at temp *f +3
+ at default */p2 +2 :tip
+@ 11: r11 []
+|
+o 10: r10 []
+|
+o 9: r9 []
+|\
+| o 8: r8 [temp]
+| |
+| o 7: r7 [temp]
+| |
+| o 6: r6 [temp]
+| |
+| o 5: r5 [temp]
+| |
+o | 4: r4 []
+| |
+o | 3: r3 []
+| |
+o | 2: r2 []
+|/
+o 1: r1 []
+|
+o 0: r0 []
+
+manifest r4
+f0
+f1
+f2
+f3
+f4
+manifest r8
+f0
+f1
+f5
+f6
+f7
+f8
+manifest tip
+f0
+f1
+f10
+f11
+f2
+f3
+f4
+f5
+f6
+f7
+f8
+f9
+---- append
++2 :f
++3 :p2
+ at temp *f +3
+ at default */p2 +2 :tip
+@ 11: r11 []
+|
+o 10: r10 []
+|
+o 9: r9 []
+|\
+| o 8: r8 [temp]
+| |
+| o 7: r7 [temp]
+| |
+| o 6: r6 [temp]
+| |
+| o 5: r5 [temp]
+| |
+o | 4: r4 []
+| |
+o | 3: r3 []
+| |
+o | 2: r2 []
+|/
+o 1: r1 []
+|
+o 0: r0 []
+
+@ 11: r11 []
+|
+o 10: r10 []
+|
+o 9: r9 []
+|\
+| o 8: r8 [temp]
+| |
+| o 7: r7 [temp]
+| |
+| o 6: r6 [temp]
+| |
+| o 5: r5 [temp]
+| |
+o | 4: r4 []
+| |
+o | 3: r3 []
+| |
+o | 2: r2 []
+|/
+o 1: r1 []
+|
+o 0: r0 []
+
+rev0
+rev1
+rev5
+rev6
+rev7
+rev8
+rev9
+rev10
+rev11
+---- command
++4 :tip
+@ 3: r3 []
+|
+o 2: r2 []
+|
+o 1: r1 []
+|
+o 0: r0 []
+
+o 2: r2 []
+
More information about the Mercurial-devel
mailing list