graphmod/graphlog: make dag walks carry data as type, payload
authorPeter Arrenbrecht <peter.arrenbrecht@gmail.com>
Fri, 19 Jun 2009 13:22:32 +0200
changeset 8840 d9acbe7b0049
parent 8839 bbfa21b6f18a
child 8841 94ac080e7af9
graphmod/graphlog: make dag walks carry data as type, payload
hgext/graphlog.py
mercurial/graphmod.py
--- a/hgext/graphlog.py	Sat May 16 07:12:12 2009 +0200
+++ b/hgext/graphlog.py	Fri Jun 19 13:22:32 2009 +0200
@@ -20,27 +20,24 @@
 from mercurial import bundlerepo, changegroup, cmdutil, commands, extensions
 from mercurial import hg, url, util, graphmod
 
+ASCIIDATA = 'ASC'
+
 def asciiformat(ui, repo, revdag, opts):
     """formats a changelog DAG walk for ASCII output"""
     showparents = [ctx.node() for ctx in repo[None].parents()]
     displayer = show_changeset(ui, repo, opts, buffered=True)
-    for (ctx, parents) in revdag:
+    for (id, type, ctx, parentids) in revdag:
+        if type != graphmod.CHANGESET:
+            continue
         displayer.show(ctx)
         lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1]
         char = ctx.node() in showparents and '@' or 'o'
-        yield (ctx.rev(), parents, char, lines)
+        yield (id, ASCIIDATA, (char, lines), parentids)
 
 def asciiedges(nodes):
-    """adds edge info to ascii formatted changelog DAG walk suitable for ascii()
-
-    nodes must generate tuples (node, parents, char, lines) where
-     - parents must generate the parents of node, in sorted order,
-       and max length 2,
-     - char is the char to print as the node symbol, and
-     - lines are the lines to display next to the node.
-    """
+    """adds edge info to changelog DAG walk suitable for ascii()"""
     seen = []
-    for node, parents, char, lines in nodes:
+    for node, type, data, parents in nodes:
         if node not in seen:
             seen.append(node)
         nodeidx = seen.index(node)
@@ -64,7 +61,7 @@
             edges.append((nodeidx, nodeidx + 1))
         nmorecols = len(nextseen) - ncols
         seen = nextseen
-        yield (char, lines, nodeidx, edges, ncols, nmorecols)
+        yield (nodeidx, type, data, edges, ncols, nmorecols)
 
 def fix_long_right_edges(edges):
     for (i, (start, end)) in enumerate(edges):
@@ -123,9 +120,11 @@
 
     dag is a generator that emits tuples with the following elements:
 
-      - 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.
+      - 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.
       - 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.
@@ -136,7 +135,7 @@
     """
     prev_n_columns_diff = 0
     prev_node_index = 0
-    for (node_ch, node_lines, node_index, edges, n_columns, n_columns_diff) in dag:
+    for (node_index, type, (node_ch, node_lines), edges, n_columns, n_columns_diff) in dag:
 
         assert -2 < n_columns_diff < 2
         if n_columns_diff == -1:
--- a/mercurial/graphmod.py	Sat May 16 07:12:12 2009 +0200
+++ b/mercurial/graphmod.py	Fri Jun 19 13:22:32 2009 +0200
@@ -6,25 +6,39 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2, incorporated herein by reference.
 
-from node import nullrev
+"""supports walking the history as DAGs suitable for graphical output
+
+The most basic format we use is that of::
+
+  (id, type, data, [parentids])
+
+The node and parent ids are arbitrary integers which identify a node in the
+context of the graph returned. Type is a constant specifying the node type.
+Data depends on type.
+"""
+
+from mercurial.node import nullrev
+
+CHANGESET = 'C'
 
 def revisions(repo, start, stop):
-    """cset DAG generator yielding (rev, node, [parents]) tuples
+    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
 
     This generator function walks through the revision history from revision
-    start to revision stop (which must be less than or equal to start).
+    start to revision stop (which must be less than or equal to start). It
+    returns a tuple for each node. The node and parent ids are arbitrary
+    integers which identify a node in the context of the graph returned.
     """
     assert start >= stop
     cur = start
     while cur >= stop:
         ctx = repo[cur]
         parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev]
-        parents.sort()
-        yield (ctx, parents)
+        yield (cur, CHANGESET, ctx, sorted(parents))
         cur -= 1
 
 def filerevs(repo, path, start, stop):
-    """file cset DAG generator yielding (rev, node, [parents]) tuples
+    """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
 
     This generator function walks through the revision history of a single
     file from revision start to revision stop (which must be less than or
@@ -35,20 +49,24 @@
     while filerev >= 0:
         fctx = repo.filectx(path, fileid=filerev)
         parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
-        parents.sort()
-        if fctx.rev() <= start:
-            yield (fctx, parents)
-        if fctx.rev() <= stop:
+        rev = fctx.rev()
+        if rev <= start:
+            yield (rev, CHANGESET, fctx, sorted(parents))
+        if rev <= stop:
             break
         filerev -= 1
 
 def nodes(repo, nodes):
+    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
+
+    This generator function walks the given nodes. It only returns parents
+    that are in nodes, too.
+    """
     include = set(nodes)
     for node in nodes:
         ctx = repo[node]
         parents = [p.rev() for p in ctx.parents() if p.node() in include]
-        parents.sort()
-        yield (ctx, parents)
+        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
 
 def graph(repo, start_rev, stop_rev):
     """incremental revision grapher