mercurial/graphmod.py
author Matt Mackall <mpm@selenic.com>
Fri, 06 Mar 2009 09:15:47 -0600
changeset 7826 f0a7accf1d68
parent 7565 5f162f61e479
child 7873 4a4c7f6a5912
permissions -rw-r--r--
setup.py: fix version detection for tarball - don't do version detection if there's no .hg directory - shrink try: clause - don't write __version__.py if version is unknown (we might overwrite the real version)

# 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
    """

    if start_rev == nullrev and not stop_rev:
        return

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

    while curr_rev >= stop_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