eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/graphmod.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 # Revision graph generator for Mercurial
       
     2 #
       
     3 # Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
       
     4 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
       
     5 #
       
     6 # This software may be used and distributed according to the terms of the
       
     7 # GNU General Public License version 2 or any later version.
       
     8 
       
     9 """supports walking the history as DAGs suitable for graphical output
       
    10 
       
    11 The most basic format we use is that of::
       
    12 
       
    13   (id, type, data, [parentids])
       
    14 
       
    15 The node and parent ids are arbitrary integers which identify a node in the
       
    16 context of the graph returned. Type is a constant specifying the node type.
       
    17 Data depends on type.
       
    18 """
       
    19 
       
    20 from mercurial.node import nullrev
       
    21 
       
    22 CHANGESET = 'C'
       
    23 
       
    24 def revisions(repo, start, stop):
       
    25     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
       
    26 
       
    27     This generator function walks through the revision history from revision
       
    28     start to revision stop (which must be less than or equal to start). It
       
    29     returns a tuple for each node. The node and parent ids are arbitrary
       
    30     integers which identify a node in the context of the graph returned.
       
    31     """
       
    32     cur = start
       
    33     while cur >= stop:
       
    34         ctx = repo[cur]
       
    35         parents = set([p.rev() for p in ctx.parents() if p.rev() != nullrev])
       
    36         yield (cur, CHANGESET, ctx, sorted(parents))
       
    37         cur -= 1
       
    38 
       
    39 def filerevs(repo, path, start, stop, limit=None):
       
    40     """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
       
    41 
       
    42     This generator function walks through the revision history of a single
       
    43     file from revision start down to revision stop.
       
    44     """
       
    45     filerev = len(repo.file(path)) - 1
       
    46     rev = stop + 1
       
    47     count = 0
       
    48     while filerev >= 0 and rev > stop:
       
    49         fctx = repo.filectx(path, fileid=filerev)
       
    50         parents = set([f.linkrev() for f in fctx.parents() if f.path() == path])
       
    51         rev = fctx.rev()
       
    52         if rev <= start:
       
    53             yield (rev, CHANGESET, fctx.changectx(), sorted(parents))
       
    54             count += 1
       
    55             if count == limit:
       
    56                 break
       
    57         filerev -= 1
       
    58 
       
    59 def nodes(repo, nodes):
       
    60     """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
       
    61 
       
    62     This generator function walks the given nodes. It only returns parents
       
    63     that are in nodes, too.
       
    64     """
       
    65     include = set(nodes)
       
    66     for node in nodes:
       
    67         ctx = repo[node]
       
    68         parents = set([p.rev() for p in ctx.parents() if p.node() in include])
       
    69         yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
       
    70 
       
    71 def colored(dag):
       
    72     """annotates a DAG with colored edge information
       
    73 
       
    74     For each DAG node this function emits tuples::
       
    75 
       
    76       (id, type, data, (col, color), [(col, nextcol, color)])
       
    77 
       
    78     with the following new elements:
       
    79 
       
    80       - Tuple (col, color) with column and color index for the current node
       
    81       - A list of tuples indicating the edges between the current node and its
       
    82         parents.
       
    83     """
       
    84     seen = []
       
    85     colors = {}
       
    86     newcolor = 1
       
    87     for (cur, type, data, parents) in dag:
       
    88 
       
    89         # Compute seen and next
       
    90         if cur not in seen:
       
    91             seen.append(cur) # new head
       
    92             colors[cur] = newcolor
       
    93             newcolor += 1
       
    94 
       
    95         col = seen.index(cur)
       
    96         color = colors.pop(cur)
       
    97         next = seen[:]
       
    98 
       
    99         # Add parents to next
       
   100         addparents = [p for p in parents if p not in next]
       
   101         next[col:col + 1] = addparents
       
   102 
       
   103         # Set colors for the parents
       
   104         for i, p in enumerate(addparents):
       
   105             if not i:
       
   106                 colors[p] = color
       
   107             else:
       
   108                 colors[p] = newcolor
       
   109                 newcolor += 1
       
   110 
       
   111         # Add edges to the graph
       
   112         edges = []
       
   113         for ecol, eid in enumerate(seen):
       
   114             if eid in next:
       
   115                 edges.append((ecol, next.index(eid), colors[eid]))
       
   116             elif eid == cur:
       
   117                 for p in parents:
       
   118                     edges.append((ecol, next.index(p), color))
       
   119 
       
   120         # Yield and move on
       
   121         yield (cur, type, data, (col, color), edges)
       
   122         seen = next