mercurial/graphmod.py
author Martin Geisler <mg@daimi.au.dk>
Sat, 16 Aug 2008 16:32:57 +0200
changeset 6914 95f35b553ae6
parent 6747 f6c00b17387c
child 7030 20a5dd5d6dd9
permissions -rw-r--r--
hgweb: removed unnecessary del before function return Deleting tmpl just before the return statement should have no effect since tmpl goes out of scope anyway. But it confuses pyflakes who thinks tmpl is undefined when it is used in the except blocks below.

# Revision graph generator for Mercurial
#
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
#
# This software may be used and distributed according to the terms of
# the GNU General Public License, incorporated herein by reference.

from node import nullrev, short
import ui, hg, util, templatefilters

def graph(repo, start_rev, stop_rev):
    """incremental revision grapher

    This generator function walks through the revision history from
    revision start_rev to revision stop_rev (which must be less than
    or equal to start_rev) and for each revision emits tuples with the
    following elements:

      - Current node
      - Column and color for the current node
      - Edges; a list of (col, next_col, color) indicating the edges between
        the current node and its parents.
      - First line of the changeset description
      - The changeset author
      - The changeset date/time
    """

    assert start_rev >= stop_rev
    curr_rev = start_rev
    revs = []
    cl = repo.changelog
    colors = {}
    new_color = 1

    while curr_rev >= stop_rev:
        node = cl.node(curr_rev)

        # Compute revs and next_revs
        if curr_rev not in revs:
            revs.append(curr_rev) # new head
            colors[curr_rev] = new_color
            new_color += 1

        idx = revs.index(curr_rev)
        color = colors.pop(curr_rev)
        next = revs[:]

        # Add parents to next_revs
        parents = [x for x in cl.parentrevs(curr_rev) if x != nullrev]
        addparents = [p for p in parents if p not in next]
        next[idx:idx + 1] = addparents

        # Set colors for the parents
        for i, p in enumerate(addparents):
            if not i:
                colors[p] = color
            else:
                colors[p] = new_color
                new_color += 1

        # Add edges to the graph
        edges = []
        for col, r in enumerate(revs):
            if r in next:
                edges.append((col, next.index(r), colors[r]))
            elif r == curr_rev:
                for p in parents:
                    edges.append((col, next.index(p), colors[p]))

        # Yield and move on
        yield (repo[curr_rev], (idx, color), edges)
        revs = next
        curr_rev -= 1