|
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 |
|
7 # the GNU General Public License, incorporated herein by reference. |
|
8 |
|
9 from node import nullrev, short |
|
10 import ui, hg, util, templatefilters |
|
11 |
|
12 def graph(repo, start_rev, stop_rev): |
|
13 """incremental revision grapher |
|
14 |
|
15 This generator function walks through the revision history from |
|
16 revision start_rev to revision stop_rev (which must be less than |
|
17 or equal to start_rev) and for each revision emits tuples with the |
|
18 following elements: |
|
19 |
|
20 - Current node |
|
21 - Column and color for the current node |
|
22 - Edges; a list of (col, next_col, color) indicating the edges between |
|
23 the current node and its parents. |
|
24 - First line of the changeset description |
|
25 - The changeset author |
|
26 - The changeset date/time |
|
27 """ |
|
28 |
|
29 assert start_rev >= stop_rev |
|
30 curr_rev = start_rev |
|
31 revs = [] |
|
32 cl = repo.changelog |
|
33 colors = {} |
|
34 new_color = 1 |
|
35 |
|
36 while curr_rev >= stop_rev: |
|
37 node = cl.node(curr_rev) |
|
38 |
|
39 # Compute revs and next_revs |
|
40 if curr_rev not in revs: |
|
41 revs.append(curr_rev) # new head |
|
42 colors[curr_rev] = new_color |
|
43 new_color += 1 |
|
44 |
|
45 idx = revs.index(curr_rev) |
|
46 color = colors.pop(curr_rev) |
|
47 next = revs[:] |
|
48 |
|
49 # Add parents to next_revs |
|
50 parents = [x for x in cl.parentrevs(curr_rev) if x != nullrev] |
|
51 addparents = [p for p in parents if p not in next] |
|
52 next[idx:idx + 1] = addparents |
|
53 |
|
54 # Set colors for the parents |
|
55 for i, p in enumerate(addparents): |
|
56 if not i: |
|
57 colors[p] = color |
|
58 else: |
|
59 colors[p] = new_color |
|
60 new_color += 1 |
|
61 |
|
62 # Add edges to the graph |
|
63 edges = [] |
|
64 for col, r in enumerate(revs): |
|
65 if r in next: |
|
66 edges.append((col, next.index(r), colors[r])) |
|
67 elif r == curr_rev: |
|
68 for p in parents: |
|
69 edges.append((col, next.index(p), colors[p])) |
|
70 |
|
71 # Yield and move on |
|
72 yield (repo.changectx(curr_rev), (idx, color), edges) |
|
73 revs = next |
|
74 curr_rev -= 1 |