view mercurial/graphmod.py @ 7059:6a76cf980999

Improve error handling in osutil.c 1) In posix part set error when path is too long so instead of SystemError: error returned without exception set it will raise ValueError: path too long 2) In Win32 part replace generic PyErr_SetExcFromWindowsErrWithFilename by PyErr_SetFromWindowsErrWithFilename The exception returned is WinError(based on OSError) and some rudimentary errno translation is performed from Windows error range to errno module friendly range so errors like ENOENT can be handled via symbolic constant and consistently between Win32 and Posix.
author Petr Kodl <petrkodl@gmail.com>
date Wed, 01 Oct 2008 08:41:18 -0400
parents 20a5dd5d6dd9
children 810ca383da9c
line wrap: on
line source

# 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
    assert stop_rev >= 0
    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