##// END OF EJS Templates
httpconnection: correctly handle redirects from http to https...
httpconnection: correctly handle redirects from http to https Previously the connection cache for keepalives didn't keep track of ssl. This meant that when we connected to an https server after that same server via http, both on the default port, we'd incorrectly reuse the non-https connection as the default port meant the connection cache key was the same.

File last commit:

r14319:b33f3e35 default
r14346:bf85c263 default
Show More
graphlog.py
397 lines | 13.0 KiB | text/x-python | PythonLexer
Joel Rosdahl
Add graphlog extension
r4344 # ASCII graph log extension for Mercurial
#
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
Thomas Arendsen Hein
Removed trailing whitespace and tabs from python files
r4516 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Martin Geisler
add blank line after copyright notices and after header
r8228
Dirkjan Ochtman
extensions: change descriptions for extensions providing a few commands
r8934 '''command to view revision graphs from a shell
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
This extension adds a --graph option to the incoming, outgoing and log
Martin Geisler
graphlog: wrap docstrings at 70 characters
r9259 commands. When this options is given, an ASCII representation of the
revision graph is also shown.
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 '''
Joel Rosdahl
Add graphlog extension
r4344
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 from mercurial.cmdutil import show_changeset
Peter Arrenbrecht
cleanup: drop unused imports
r7873 from mercurial.commands import templateopts
Joel Rosdahl
Add graphlog extension
r4344 from mercurial.i18n import _
Joel Rosdahl
Remove unused imports
r6212 from mercurial.node import nullrev
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 from mercurial import cmdutil, commands, extensions, scmutil
timeless
remove unused imports
r14139 from mercurial import hg, util, graphmod
Steve Borho
graphlog: add filelog revision grapher...
r5938
Adrian Buehlmann
graphlog: use cmdutil.command decorator
r14311 cmdtable = {}
command = cmdutil.command(cmdtable)
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 ASCIIDATA = 'ASC'
Patrick Mezard
graphlog: display nodes with more than 2 predecessors...
r14130 def asciiedges(type, char, lines, seen, rev, parents):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """adds edge info to changelog DAG walk suitable for ascii()"""
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369 if rev not in seen:
seen.append(rev)
nodeidx = seen.index(rev)
Steve Borho
graphlog: add filelog revision grapher...
r5938
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369 knownparents = []
newparents = []
for parent in parents:
if parent in seen:
knownparents.append(parent)
else:
newparents.append(parent)
Steve Borho
graphlog: add filelog revision grapher...
r5938
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369 ncols = len(seen)
Patrick Mezard
graphlog: display nodes with more than 2 predecessors...
r14130 nextseen = seen[:]
nextseen[nodeidx:nodeidx + 1] = newparents
edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
while len(newparents) > 2:
# ascii() only knows how to add or remove a single column between two
# calls. Nodes with more than two parents break this constraint so we
# introduce intermediate expansion lines to grow the active node list
# slowly.
edges.append((nodeidx, nodeidx))
edges.append((nodeidx, nodeidx + 1))
nmorecols = 1
yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
char = '\\'
lines = []
nodeidx += 1
ncols += 1
edges = []
del newparents[0]
Peter Arrenbrecht
graphlog: refactor common grapher code...
r7370
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369 if len(newparents) > 0:
edges.append((nodeidx, nodeidx))
if len(newparents) > 1:
edges.append((nodeidx, nodeidx + 1))
Patrick Mezard
graphlog: display nodes with more than 2 predecessors...
r14130 nmorecols = len(nextseen) - ncols
seen[:] = nextseen
yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
Steve Borho
graphlog: add filelog revision grapher...
r5938
Joel Rosdahl
Add graphlog extension
r4344 def fix_long_right_edges(edges):
for (i, (start, end)) in enumerate(edges):
if end > start:
edges[i] = (start, end + 1)
Dirkjan Ochtman
graphlog: move functions around, eliminate helper function...
r7326 def get_nodeline_edges_tail(
node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
# Still going in the same non-vertical direction.
if n_columns_diff == -1:
start = max(node_index + 1, p_node_index)
tail = ["|", " "] * (start - node_index - 1)
tail.extend(["/", " "] * (n_columns - start))
return tail
else:
return ["\\", " "] * (n_columns - node_index - 1)
else:
return ["|", " "] * (n_columns - node_index - 1)
Joel Rosdahl
Add graphlog extension
r4344 def draw_edges(edges, nodeline, interline):
for (start, end) in edges:
if start == end + 1:
interline[2 * end + 1] = "/"
elif start == end - 1:
interline[2 * start + 1] = "\\"
elif start == end:
interline[2 * start] = "|"
else:
nodeline[2 * end] = "+"
if start > end:
Martin Geisler
coding style: use a space after comma...
r9198 (start, end) = (end, start)
Joel Rosdahl
Add graphlog extension
r4344 for i in range(2 * start + 1, 2 * end):
if nodeline[i] != "+":
nodeline[i] = "-"
def get_padding_line(ni, n_columns, edges):
line = []
line.extend(["|", " "] * ni)
if (ni, ni - 1) in edges or (ni, ni) in edges:
# (ni, ni - 1) (ni, ni)
# | | | | | | | |
# +---o | | o---+
# | | c | | c | |
# | |/ / | |/ /
# | | | | | |
c = "|"
else:
c = " "
line.extend([c, " "])
line.extend(["|", " "] * (n_columns - ni - 1))
return line
Peter Arrenbrecht
graphlog: hide internal state of ascii() from users
r9631 def asciistate():
"""returns the initial value for the "state" argument to ascii()"""
return [0, 0]
def ascii(ui, state, type, char, text, coldata):
Peter Arrenbrecht
graphlog: rename grapher to asciiedges
r8839 """prints an ASCII graph of the DAG
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 takes the following arguments (one call per node in the graph):
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 - ui to write to
Peter Arrenbrecht
graphlog: hide internal state of ascii() from users
r9631 - Somewhere to keep the needed state in (init to asciistate())
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325 - Column of the current node in the set of ongoing edges.
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 - Type indicator of node data == ASCIIDATA.
- Payload: (char, lines):
- Character to use as node's symbol.
- List of lines to display as the node's text.
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325 - Edges; a list of (col, next_col) indicating the edges between
the current node and its parents.
- Number of columns (ongoing edges) in the current revision.
- The difference between the number of columns (ongoing edges)
in the next revision and the number of columns (ongoing edges)
in the current revision. That is: -1 means one column removed;
0 means no columns added or removed; 1 means one column added.
"""
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 idx, edges, ncols, coldiff = coldata
assert -2 < coldiff < 2
if coldiff == -1:
# Transform
Joel Rosdahl
Add graphlog extension
r4344 #
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # | | | | | |
# o | | into o---+
# |X / |/ /
# | | | |
fix_long_right_edges(edges)
# add_padding_line says whether to rewrite
#
# | | | | | | | |
# | o---+ into | o---+
# | / / | | | # <--- padding line
# o | | | / /
# o | |
add_padding_line = (len(text) > 2 and coldiff == -1 and
[x for (x, y) in edges if x + 1 < y])
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # fix_nodeline_tail says whether to rewrite
#
# | | o | | | | o | |
# | | |/ / | | |/ /
# | o | | into | o / / # <--- fixed nodeline tail
# | |/ / | |/ /
# o | | o | |
fix_nodeline_tail = len(text) <= 2 and not add_padding_line
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # nodeline is the line containing the node character (typically o)
nodeline = ["|", " "] * idx
nodeline.extend([char, " "])
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 nodeline.extend(
Peter Arrenbrecht
graphlog: hide internal state of ascii() from users
r9631 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
state[0], fix_nodeline_tail))
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # shift_interline is the line containing the non-vertical
# edges between this entry and the next
shift_interline = ["|", " "] * idx
if coldiff == -1:
n_spaces = 1
edge_ch = "/"
elif coldiff == 0:
n_spaces = 2
edge_ch = "|"
else:
n_spaces = 3
edge_ch = "\\"
shift_interline.extend(n_spaces * [" "])
shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # draw edges from the current node to its parents
draw_edges(edges, nodeline, shift_interline)
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # lines is the list of all graph lines to print
lines = [nodeline]
if add_padding_line:
lines.append(get_padding_line(idx, ncols, edges))
lines.append(shift_interline)
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # make sure that there are as many graph lines as there are
# log strings
while len(text) < len(lines):
text.append("")
if len(lines) < len(text):
extra_interline = ["|", " "] * (ncols + coldiff)
while len(lines) < len(text):
lines.append(extra_interline)
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # print lines
indentation_level = max(ncols, ncols + coldiff)
for (line, logstr) in zip(lines, text):
ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
ui.write(ln.rstrip() + '\n')
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 # ... and start over
Peter Arrenbrecht
graphlog: hide internal state of ascii() from users
r9631 state[0] = coldiff
state[1] = idx
Joel Rosdahl
Add graphlog extension
r4344
Dirkjan Ochtman
graphlog: move functions around, eliminate helper function...
r7326 def get_revs(repo, rev_opt):
if rev_opt:
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = scmutil.revrange(repo, rev_opt)
Eric Eisner
glog: fix crash on empty revision range
r11448 if len(revs) == 0:
return (nullrev, nullrev)
Dirkjan Ochtman
graphlog: move functions around, eliminate helper function...
r7326 return (max(revs), min(revs))
else:
return (len(repo) - 1, 0)
Patrick Mezard
graphlog: log -G --follow file does not work, forbid it...
r14086 def check_unsupported_flags(pats, opts):
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 for op in ["follow_first", "copies", "newest_first"]:
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 if op in opts and opts[op]:
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 raise util.Abort(_("-G/--graph option is incompatible with --%s")
Greg Ward
glog: fix "incompatible option" error message....
r10097 % op.replace("_", "-"))
Patrick Mezard
graphlog: log -G --follow file does not work, forbid it...
r14086 if pats and opts.get('follow'):
raise util.Abort(_("-G/--graph option is incompatible with --follow "
"with file argument"))
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 def revset(pats, opts):
"""Return revset str built of revisions, log options and file patterns.
"""
Patrick Mezard
graphlog: unify log -G revset translation
r14085 opt2revset = {
'follow': (0, 'follow()'),
'no_merges': (0, 'not merge()'),
'only_merges': (0, 'merge()'),
'removed': (0, 'removes("*")'),
'date': (1, 'date($)'),
'branch': (2, 'branch($)'),
'exclude': (2, 'not file($)'),
'include': (2, 'file($)'),
'keyword': (2, 'keyword($)'),
'only_branch': (2, 'branch($)'),
'prune': (2, 'not ($ or ancestors($))'),
'user': (2, 'user($)'),
}
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 optrevset = []
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 revset = []
for op, val in opts.iteritems():
if not val:
continue
Patrick Mezard
graphlog: unify log -G revset translation
r14085 if op == 'rev':
# Already a revset
revset.extend(val)
if op not in opt2revset:
continue
arity, revop = opt2revset[op]
revop = revop.replace('$', '%(val)r')
if arity == 0:
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 optrevset.append(revop)
Patrick Mezard
graphlog: unify log -G revset translation
r14085 elif arity == 1:
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 optrevset.append(revop % {'val': val})
Patrick Mezard
graphlog: unify log -G revset translation
r14085 else:
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 for f in val:
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 optrevset.append(revop % {'val': f})
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043
for path in pats:
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 optrevset.append('file(%r)' % path)
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043
Patrick Mezard
graphlog: take the union of --rev specs instead of the intersection
r14132 if revset or optrevset:
if revset:
revset = ['(' + ' or '.join(revset) + ')']
if optrevset:
revset.append('(' + ' and '.join(optrevset) + ')')
revset = ' and '.join(revset)
else:
revset = 'all()'
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 return revset
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 def generate(ui, dag, displayer, showparents, edgefn):
Peter Arrenbrecht
graphlog: hide internal state of ascii() from users
r9631 seen, state = [], asciistate()
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369 for rev, type, ctx, parents in dag:
char = ctx.node() in showparents and '@' or 'o'
displayer.show(ctx)
lines = displayer.hunk.pop(rev).split('\n')[:-1]
Mads Kiilerich
graphlog: style with header and footer (issue2395)...
r12579 displayer.flush(rev)
Patrick Mezard
graphlog: display nodes with more than 2 predecessors...
r14130 edges = edgefn(type, char, lines, seen, rev, parents)
for type, char, lines, coldata in edges:
ascii(ui, state, type, char, lines, coldata)
Mads Kiilerich
graphlog: style with header and footer (issue2395)...
r12579 displayer.close()
Dirkjan Ochtman
graphlog: move common code into function again, change function types
r9369
Adrian Buehlmann
graphlog: use cmdutil.command decorator
r14311 @command('glog',
[('l', 'limit', '',
_('limit number of changes displayed'), _('NUM')),
('p', 'patch', False, _('show patch')),
('r', 'rev', [], _('show the specified revision or range'), _('REV')),
] + templateopts,
_('hg glog [OPTION]... [FILE]'))
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 def graphlog(ui, repo, *pats, **opts):
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325 """show revision history alongside an ASCII revision graph
Martin Geisler
graphlog: wrap docstrings at 70 characters
r9259 Print a revision history alongside a revision graph drawn with
ASCII characters.
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325
Martin Geisler
graphlog: wrap docstrings at 70 characters
r9259 Nodes printed as an @ character are parents of the working
directory.
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325 """
Patrick Mezard
graphlog: log -G --follow file does not work, forbid it...
r14086 check_unsupported_flags(pats, opts)
Peter Arrenbrecht
graphlog: refactor common grapher code...
r7370
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = sorted(scmutil.revrange(repo, [revset(pats, opts)]), reverse=1)
Patrick Mezard
graphlog: always sort revisions topologically...
r14133 limit = cmdutil.loglimit(opts)
if limit is not None:
revs = revs[:limit]
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 revdag = graphmod.dagwalker(repo, revs)
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325
Dirkjan Ochtman
graphlog: extract some setup code out of common functions
r9368 displayer = show_changeset(ui, repo, opts, buffered=True)
showparents = [ctx.node() for ctx in repo[None].parents()]
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 generate(ui, revdag, displayer, showparents, asciiedges)
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716
def graphrevs(repo, nodes, opts):
limit = cmdutil.loglimit(opts)
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 nodes.reverse()
Nicolas Dumazet
cmdutil: replace sys.maxint with None as default value in loglimit...
r10111 if limit is not None:
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 nodes = nodes[:limit]
return graphmod.nodes(repo, nodes)
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716
def goutgoing(ui, repo, dest=None, **opts):
"""show the outgoing changesets alongside an ASCII revision graph
Peter Arrenbrecht
graphlog: split the actual DAG grapher out into a separate method...
r7325
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716 Print the outgoing changesets alongside a revision graph drawn with
ASCII characters.
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716 Nodes printed as an @ character are parents of the working
directory.
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 """
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716
Patrick Mezard
graphlog: log -G --follow file does not work, forbid it...
r14086 check_unsupported_flags([], opts)
Nicolas Dumazet
outgoing: unify common graphlog.outgoing and hg.outgoing code
r12735 o = hg._outgoing(ui, repo, dest, opts)
if o is None:
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 return
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716
revdag = graphrevs(repo, o, opts)
Dirkjan Ochtman
graphlog: extract some setup code out of common functions
r9368 displayer = show_changeset(ui, repo, opts, buffered=True)
showparents = [ctx.node() for ctx in repo[None].parents()]
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 generate(ui, revdag, displayer, showparents, asciiedges)
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
def gincoming(ui, repo, source="default", **opts):
"""show the incoming changesets alongside an ASCII revision graph
Martin Geisler
graphlog: wrap docstrings at 70 characters
r9259 Print the incoming changesets alongside a revision graph drawn with
ASCII characters.
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
Martin Geisler
graphlog: wrap docstrings at 70 characters
r9259 Nodes printed as an @ character are parents of the working
directory.
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 """
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 def subreporecurse():
return 1
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
Patrick Mezard
graphlog: log -G --follow file does not work, forbid it...
r14086 check_unsupported_flags([], opts)
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 def display(other, chlist, displayer):
Dirkjan Ochtman
graphlog: extract large parts of repeated code from incoming/outgoing
r7716 revdag = graphrevs(other, chlist, opts)
Dirkjan Ochtman
graphlog: extract some setup code out of common functions
r9368 showparents = [ctx.node() for ctx in repo[None].parents()]
Dirkjan Ochtman
graphlog: simplify ascii drawing to process one cset at a time
r9371 generate(ui, revdag, displayer, showparents, asciiedges)
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
Nicolas Dumazet
incoming: unify code for incoming and graphlog.incoming
r12730 hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426
def uisetup(ui):
'''Initialize the extension.'''
_wrapcmd(ui, 'log', commands.table, graphlog)
_wrapcmd(ui, 'incoming', commands.table, gincoming)
_wrapcmd(ui, 'outgoing', commands.table, goutgoing)
def _wrapcmd(ui, cmd, table, wrapfn):
'''wrap the command'''
def graph(orig, *args, **kwargs):
if kwargs['graph']:
Alexander Solovyov
graphlog: make use of graphmod's revset support
r14043 return wrapfn(*args, **kwargs)
Alpar Juttner
Graphlog extension adds a --graph option to log/in/out...
r7426 return orig(*args, **kwargs)
entry = extensions.wrapcommand(table, cmd, graph)
Jim Correia
log-like commands now use -G for --graph, -g for --git
r7763 entry[1].append(('G', 'graph', None, _("show the revision DAG")))