Show More
@@ -20,27 +20,24 b' from mercurial.node import nullrev' | |||||
20 | from mercurial import bundlerepo, changegroup, cmdutil, commands, extensions |
|
20 | from mercurial import bundlerepo, changegroup, cmdutil, commands, extensions | |
21 | from mercurial import hg, url, util, graphmod |
|
21 | from mercurial import hg, url, util, graphmod | |
22 |
|
22 | |||
|
23 | ASCIIDATA = 'ASC' | |||
|
24 | ||||
23 | def asciiformat(ui, repo, revdag, opts): |
|
25 | def asciiformat(ui, repo, revdag, opts): | |
24 | """formats a changelog DAG walk for ASCII output""" |
|
26 | """formats a changelog DAG walk for ASCII output""" | |
25 | showparents = [ctx.node() for ctx in repo[None].parents()] |
|
27 | showparents = [ctx.node() for ctx in repo[None].parents()] | |
26 | displayer = show_changeset(ui, repo, opts, buffered=True) |
|
28 | displayer = show_changeset(ui, repo, opts, buffered=True) | |
27 | for (ctx, parents) in revdag: |
|
29 | for (id, type, ctx, parentids) in revdag: | |
|
30 | if type != graphmod.CHANGESET: | |||
|
31 | continue | |||
28 | displayer.show(ctx) |
|
32 | displayer.show(ctx) | |
29 | lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1] |
|
33 | lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1] | |
30 | char = ctx.node() in showparents and '@' or 'o' |
|
34 | char = ctx.node() in showparents and '@' or 'o' | |
31 |
yield ( |
|
35 | yield (id, ASCIIDATA, (char, lines), parentids) | |
32 |
|
36 | |||
33 | def asciiedges(nodes): |
|
37 | def asciiedges(nodes): | |
34 |
"""adds edge info to |
|
38 | """adds edge info to changelog DAG walk suitable for ascii()""" | |
35 |
|
||||
36 | nodes must generate tuples (node, parents, char, lines) where |
|
|||
37 | - parents must generate the parents of node, in sorted order, |
|
|||
38 | and max length 2, |
|
|||
39 | - char is the char to print as the node symbol, and |
|
|||
40 | - lines are the lines to display next to the node. |
|
|||
41 | """ |
|
|||
42 | seen = [] |
|
39 | seen = [] | |
43 |
for node, p |
|
40 | for node, type, data, parents in nodes: | |
44 | if node not in seen: |
|
41 | if node not in seen: | |
45 | seen.append(node) |
|
42 | seen.append(node) | |
46 | nodeidx = seen.index(node) |
|
43 | nodeidx = seen.index(node) | |
@@ -64,7 +61,7 b' def asciiedges(nodes):' | |||||
64 | edges.append((nodeidx, nodeidx + 1)) |
|
61 | edges.append((nodeidx, nodeidx + 1)) | |
65 | nmorecols = len(nextseen) - ncols |
|
62 | nmorecols = len(nextseen) - ncols | |
66 | seen = nextseen |
|
63 | seen = nextseen | |
67 |
yield ( |
|
64 | yield (nodeidx, type, data, edges, ncols, nmorecols) | |
68 |
|
65 | |||
69 | def fix_long_right_edges(edges): |
|
66 | def fix_long_right_edges(edges): | |
70 | for (i, (start, end)) in enumerate(edges): |
|
67 | for (i, (start, end)) in enumerate(edges): | |
@@ -123,9 +120,11 b' def ascii(ui, dag):' | |||||
123 |
|
120 | |||
124 | dag is a generator that emits tuples with the following elements: |
|
121 | dag is a generator that emits tuples with the following elements: | |
125 |
|
122 | |||
126 | - Character to use as node's symbol. |
|
|||
127 | - List of lines to display as the node's text. |
|
|||
128 | - Column of the current node in the set of ongoing edges. |
|
123 | - Column of the current node in the set of ongoing edges. | |
|
124 | - Type indicator of node data == ASCIIDATA. | |||
|
125 | - Payload: (char, lines): | |||
|
126 | - Character to use as node's symbol. | |||
|
127 | - List of lines to display as the node's text. | |||
129 | - Edges; a list of (col, next_col) indicating the edges between |
|
128 | - Edges; a list of (col, next_col) indicating the edges between | |
130 | the current node and its parents. |
|
129 | the current node and its parents. | |
131 | - Number of columns (ongoing edges) in the current revision. |
|
130 | - Number of columns (ongoing edges) in the current revision. | |
@@ -136,7 +135,7 b' def ascii(ui, dag):' | |||||
136 | """ |
|
135 | """ | |
137 | prev_n_columns_diff = 0 |
|
136 | prev_n_columns_diff = 0 | |
138 | prev_node_index = 0 |
|
137 | prev_node_index = 0 | |
139 |
for (node_ch, node_lines |
|
138 | for (node_index, type, (node_ch, node_lines), edges, n_columns, n_columns_diff) in dag: | |
140 |
|
139 | |||
141 | assert -2 < n_columns_diff < 2 |
|
140 | assert -2 < n_columns_diff < 2 | |
142 | if n_columns_diff == -1: |
|
141 | if n_columns_diff == -1: |
@@ -6,25 +6,39 b'' | |||||
6 | # This software may be used and distributed according to the terms of the |
|
6 | # This software may be used and distributed according to the terms of the | |
7 | # GNU General Public License version 2, incorporated herein by reference. |
|
7 | # GNU General Public License version 2, incorporated herein by reference. | |
8 |
|
8 | |||
9 | from node import nullrev |
|
9 | """supports walking the history as DAGs suitable for graphical output | |
|
10 | ||||
|
11 | The most basic format we use is that of:: | |||
|
12 | ||||
|
13 | (id, type, data, [parentids]) | |||
|
14 | ||||
|
15 | The node and parent ids are arbitrary integers which identify a node in the | |||
|
16 | context of the graph returned. Type is a constant specifying the node type. | |||
|
17 | Data depends on type. | |||
|
18 | """ | |||
|
19 | ||||
|
20 | from mercurial.node import nullrev | |||
|
21 | ||||
|
22 | CHANGESET = 'C' | |||
10 |
|
23 | |||
11 | def revisions(repo, start, stop): |
|
24 | def revisions(repo, start, stop): | |
12 |
"""cset DAG generator yielding ( |
|
25 | """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples | |
13 |
|
26 | |||
14 | This generator function walks through the revision history from revision |
|
27 | This generator function walks through the revision history from revision | |
15 | start to revision stop (which must be less than or equal to start). |
|
28 | start to revision stop (which must be less than or equal to start). It | |
|
29 | returns a tuple for each node. The node and parent ids are arbitrary | |||
|
30 | integers which identify a node in the context of the graph returned. | |||
16 | """ |
|
31 | """ | |
17 | assert start >= stop |
|
32 | assert start >= stop | |
18 | cur = start |
|
33 | cur = start | |
19 | while cur >= stop: |
|
34 | while cur >= stop: | |
20 | ctx = repo[cur] |
|
35 | ctx = repo[cur] | |
21 | parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev] |
|
36 | parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev] | |
22 | parents.sort() |
|
37 | yield (cur, CHANGESET, ctx, sorted(parents)) | |
23 | yield (ctx, parents) |
|
|||
24 | cur -= 1 |
|
38 | cur -= 1 | |
25 |
|
39 | |||
26 | def filerevs(repo, path, start, stop): |
|
40 | def filerevs(repo, path, start, stop): | |
27 |
"""file cset DAG generator yielding ( |
|
41 | """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples | |
28 |
|
42 | |||
29 | This generator function walks through the revision history of a single |
|
43 | This generator function walks through the revision history of a single | |
30 | file from revision start to revision stop (which must be less than or |
|
44 | file from revision start to revision stop (which must be less than or | |
@@ -35,20 +49,24 b' def filerevs(repo, path, start, stop):' | |||||
35 | while filerev >= 0: |
|
49 | while filerev >= 0: | |
36 | fctx = repo.filectx(path, fileid=filerev) |
|
50 | fctx = repo.filectx(path, fileid=filerev) | |
37 | parents = [f.linkrev() for f in fctx.parents() if f.path() == path] |
|
51 | parents = [f.linkrev() for f in fctx.parents() if f.path() == path] | |
38 |
|
|
52 | rev = fctx.rev() | |
39 |
if |
|
53 | if rev <= start: | |
40 | yield (fctx, parents) |
|
54 | yield (rev, CHANGESET, fctx, sorted(parents)) | |
41 |
if |
|
55 | if rev <= stop: | |
42 | break |
|
56 | break | |
43 | filerev -= 1 |
|
57 | filerev -= 1 | |
44 |
|
58 | |||
45 | def nodes(repo, nodes): |
|
59 | def nodes(repo, nodes): | |
|
60 | """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples | |||
|
61 | ||||
|
62 | This generator function walks the given nodes. It only returns parents | |||
|
63 | that are in nodes, too. | |||
|
64 | """ | |||
46 | include = set(nodes) |
|
65 | include = set(nodes) | |
47 | for node in nodes: |
|
66 | for node in nodes: | |
48 | ctx = repo[node] |
|
67 | ctx = repo[node] | |
49 | parents = [p.rev() for p in ctx.parents() if p.node() in include] |
|
68 | parents = [p.rev() for p in ctx.parents() if p.node() in include] | |
50 | parents.sort() |
|
69 | yield (ctx.rev(), CHANGESET, ctx, sorted(parents)) | |
51 | yield (ctx, parents) |
|
|||
52 |
|
70 | |||
53 | def graph(repo, start_rev, stop_rev): |
|
71 | def graph(repo, start_rev, stop_rev): | |
54 | """incremental revision grapher |
|
72 | """incremental revision grapher |
General Comments 0
You need to be logged in to leave comments.
Login now