# Revision graph generator for Mercurial # # Copyright 2008 Dirkjan Ochtman # Copyright 2007 Joel Rosdahl # # 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 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