[PATCH 2 of 5] graphlog: split the actual DAG grapher out into a separate method
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Thu Nov 6 06:40:23 CST 2008
# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1225894450 -3600
graphlog: split the actual DAG grapher out into a separate method
This allows extensions like pbranch to use asciigraph() to graph dependencies
for patch branches, but could be used for basically any DAG.
diff --git a/hgext/graphlog.py b/hgext/graphlog.py
--- a/hgext/graphlog.py
+++ b/hgext/graphlog.py
@@ -198,38 +198,26 @@
else:
return (len(repo) - 1, 0)
-def graphlog(ui, repo, path=None, **opts):
- """show revision history alongside an ASCII revision graph
+def asciigraph(ui, grapher):
+ """prints an ASCII graph of the DAG returned by the grapher
- Print a revision history alongside a revision graph drawn with
- ASCII characters.
+ grapher is a generator that emits tuples with the following elements:
- Nodes printed as an @ character are parents of the working
- directory.
+ - Character to use as node's symbol.
+ - List of lines to display as the node's text.
+ - Column of the current node in the set of ongoing edges.
+ - 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.
"""
-
- limit = get_limit(opts["limit"])
- (start_rev, stop_rev) = get_revs(repo, opts["rev"])
- stop_rev = max(stop_rev, start_rev - limit + 1)
- if start_rev == nullrev:
- return
- cs_printer = show_changeset(ui, repo, opts)
- if path:
- path = canonpath(repo.root, os.getcwd(), path)
- if path:
- grapher = filelog_grapher(repo, path, start_rev, stop_rev)
- else:
- grapher = revision_grapher(repo, start_rev, stop_rev)
- repo_parents = repo.dirstate.parents()
prev_n_columns_diff = 0
prev_node_index = 0
-
- for (rev, node, node_index, edges, n_columns, n_columns_diff) in grapher:
- # log_strings is the list of all log strings to draw alongside
- # the graph.
- ui.pushbuffer()
- cs_printer.show(rev, node)
- log_strings = ui.popbuffer().split("\n")[:-1]
+ for (node_ch, node_lines, node_index, edges, n_columns, n_columns_diff) in grapher:
+ # node_lines is the list of all text lines to draw alongside the graph
if n_columns_diff == -1:
# Transform
@@ -247,7 +235,7 @@
# | / / | | | # <--- padding line
# o | | | / /
# o | |
- add_padding_line = (len(log_strings) > 2 and
+ add_padding_line = (len(node_lines) > 2 and
n_columns_diff == -1 and
[x for (x, y) in edges if x + 1 < y])
@@ -258,14 +246,10 @@
# | o | | into | o / / # <--- fixed nodeline tail
# | |/ / | |/ /
# o | | o | |
- fix_nodeline_tail = len(log_strings) <= 2 and not add_padding_line
+ fix_nodeline_tail = len(node_lines) <= 2 and not add_padding_line
- # nodeline is the line containing the node character (@ or o).
+ # nodeline is the line containing the node character (typically o)
nodeline = ["|", " "] * node_index
- if node in repo_parents:
- node_ch = "@"
- else:
- node_ch = "o"
nodeline.extend([node_ch, " "])
nodeline.extend(
@@ -274,7 +258,7 @@
prev_n_columns_diff, fix_nodeline_tail))
# shift_interline is the line containing the non-vertical
- # edges between this entry and the next.
+ # edges between this entry and the next
shift_interline = ["|", " "] * node_index
if n_columns_diff == -1:
n_spaces = 1
@@ -288,33 +272,72 @@
shift_interline.extend(n_spaces * [" "])
shift_interline.extend([edge_ch, " "] * (n_columns - node_index - 1))
- # Draw edges from the current node to its parents.
+ # draw edges from the current node to its parents
draw_edges(edges, nodeline, shift_interline)
- # lines is the list of all graph lines to print.
+ # lines is the list of all graph lines to print
lines = [nodeline]
if add_padding_line:
lines.append(get_padding_line(node_index, n_columns, edges))
lines.append(shift_interline)
- # Make sure that there are as many graph lines as there are
- # log strings.
- while len(log_strings) < len(lines):
- log_strings.append("")
- if len(lines) < len(log_strings):
+ # make sure that there are as many graph lines as there are
+ # log strings
+ while len(node_lines) < len(lines):
+ node_lines.append("")
+ if len(lines) < len(node_lines):
extra_interline = ["|", " "] * (n_columns + n_columns_diff)
- while len(lines) < len(log_strings):
+ while len(lines) < len(node_lines):
lines.append(extra_interline)
- # Print lines.
+ # print lines
indentation_level = max(n_columns, n_columns + n_columns_diff)
- for (line, logstr) in zip(lines, log_strings):
+ for (line, logstr) in zip(lines, node_lines):
ui.write(format_line(line, indentation_level, logstr))
- # ...and start over.
+ # ...and start over
prev_node_index = node_index
prev_n_columns_diff = n_columns_diff
+def graphlog(ui, repo, path=None, **opts):
+ """show revision history alongside an ASCII revision graph
+
+ Print a revision history alongside a revision graph drawn with
+ ASCII characters.
+
+ Nodes printed as an @ character are parents of the working
+ directory.
+ """
+
+ limit = get_limit(opts["limit"])
+ (start_rev, stop_rev) = get_revs(repo, opts["rev"])
+ stop_rev = max(stop_rev, start_rev - limit + 1)
+ if start_rev == nullrev:
+ return
+ if path:
+ path = canonpath(repo.root, os.getcwd(), path)
+ if path:
+ revgrapher = filelog_grapher(repo, path, start_rev, stop_rev)
+ else:
+ revgrapher = revision_grapher(repo, start_rev, stop_rev)
+
+ repo_parents = repo.dirstate.parents()
+ cs_printer = show_changeset(ui, repo, opts)
+ def grapher():
+ for (rev, node, node_index, edges, n_columns, n_columns_diff) in revgrapher:
+ # log_strings is the list of all log strings to draw alongside
+ # the graph.
+ ui.pushbuffer()
+ cs_printer.show(rev, node)
+ log_strings = ui.popbuffer().split("\n")[:-1]
+ if node in repo_parents:
+ node_ch = "@"
+ else:
+ node_ch = "o"
+ yield (node_ch, log_strings, node_index, edges, n_columns, n_columns_diff)
+
+ asciigraph(ui, grapher())
+
cmdtable = {
"glog":
(graphlog,
More information about the Mercurial-devel
mailing list