annotate mercurial/graphmod.py @ 18988:5bae936764bb

parsers: a C implementation of the new ancestors algorithm The performance of both the old and new Python ancestor algorithms depends on the number of revs they need to traverse. Although the new algorithm performs far better than the old when revs are numerically and topologically close, both algorithms become slow under other circumstances, taking up to 1.8 seconds to give answers in a Linux kernel repo. This C implementation of the new algorithm is a fairly straightforward transliteration. The only corner case of interest is that it raises an OverflowError if the number of GCA candidates found during the first pass is greater than 24, to avoid the dual perils of fixnum overflow and trying to allocate too much memory. (If this exception is raised, the Python implementation is used instead.) Performance numbers are good: in a Linux kernel repo, time for "hg debugancestors" on two distant revs (24bf01de7537 and c2a8808f5943) is as follows: Old Python: 0.36 sec New Python: 0.42 sec New C: 0.02 sec For a case where the new algorithm should perform well: Old Python: 1.84 sec New Python: 0.07 sec New C: measures as zero when using --time (This commit includes a paranoid cross-check to ensure that the Python and C implementations give identical answers. The above performance numbers were measured with that check disabled.)
author Bryan O'Sullivan <bryano@fb.com>
date Tue, 16 Apr 2013 10:08:20 -0700
parents e441657b372b
children e87bd3485a07
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
1 # Revision graph generator for Mercurial
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
2 #
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
3 # Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
4 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
5 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
6 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10084
diff changeset
7 # GNU General Public License version 2 or any later version.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
8
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
9 """supports walking the history as DAGs suitable for graphical output
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
10
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
11 The most basic format we use is that of::
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
12
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
13 (id, type, data, [parentids])
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
14
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
15 The node and parent ids are arbitrary integers which identify a node in the
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
16 context of the graph returned. Type is a constant specifying the node type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
17 Data depends on type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
18 """
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
19
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
20 from mercurial.node import nullrev
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
21 import util
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
22
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
23 CHANGESET = 'C'
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
24
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
25 def dagwalker(repo, revs):
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
26 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
27
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
28 This generator function walks through revisions (which should be ordered
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
29 from bigger to lower). It returns a tuple for each node. The node and parent
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
30 ids are arbitrary integers which identify a node in the context of the graph
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
31 returned.
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
32 """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
33 if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
34 return
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
35
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
36 cl = repo.changelog
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
37 lowestrev = min(revs)
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
38 gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
39
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
40 knownrevs = set(revs)
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
41 for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
42 ctx = repo[rev]
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
43 parents = sorted(set([p.rev() for p in ctx.parents()
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
44 if p.rev() in knownrevs]))
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
45 mpars = [p.rev() for p in ctx.parents() if
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
46 p.rev() != nullrev and p.rev() not in parents]
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
47
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
48 for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
49 gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
50 if gp is None:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
51 gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
52 if not gp:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
53 parents.append(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
54 else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
55 parents.extend(g for g in gp if g not in parents)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
56
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
57 yield (ctx.rev(), CHANGESET, ctx, parents)
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
58
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
59 def nodes(repo, nodes):
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
60 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
61
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
62 This generator function walks the given nodes. It only returns parents
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
63 that are in nodes, too.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
64 """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
65 include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
66 for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
67 ctx = repo[node]
12951
101366ad816c graphmod: safer code when a changeset has two identical parents
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10602
diff changeset
68 parents = set([p.rev() for p in ctx.parents() if p.node() in include])
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
69 yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
70
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
71 def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
72 """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
73
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
74 For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
75
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
76 (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
77
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
78 with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
79
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
80 - Tuple (col, color) with column and color index for the current node
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
81 - A list of tuples indicating the edges between the current node and its
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
82 parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
83 """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
84 seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
85 colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
86 newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
87 config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
88
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
89 for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
90 if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
91 branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
92 # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
93 if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
94 config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
95 elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
96 config.setdefault(branch, {})[setting] = val
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
97
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
98 if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
99 getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
100 lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
101 else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
102 getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
103
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
104 for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
105
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
106 # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
107 if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
108 seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
109 colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
110 newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
111
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
112 col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
113 color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
114 next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
115
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
116 # Add parents to next
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
117 addparents = [p for p in parents if p not in next]
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
118 next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
119
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
120 # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
121 for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
122 if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
123 colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
124 else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
125 colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
126 newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
127
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
128 # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
129 edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
130 for ecol, eid in enumerate(seen):
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
131 if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
132 bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
133 edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
134 ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
135 bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
136 bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
137 elif eid == cur:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
138 for p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
139 bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
140 edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
141 ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
142 bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
143 bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
144
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
145 # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
146 yield (cur, type, data, (col, color), edges)
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
147 seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
148
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
149 def grandparent(cl, lowestrev, roots, head):
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
150 """Return all ancestors of head in roots which revision is
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
151 greater or equal to lowestrev.
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
152 """
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
153 pending = set([head])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
154 seen = set()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
155 kept = set()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
156 llowestrev = max(nullrev, lowestrev)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
157 while pending:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
158 r = pending.pop()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
159 if r >= llowestrev and r not in seen:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
160 if r in roots:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
161 kept.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
162 else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
163 pending.update([p for p in cl.parentrevs(r)])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
164 seen.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
165 return sorted(kept)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
166
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
167 def asciiedges(type, char, lines, seen, rev, parents):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
168 """adds edge info to changelog DAG walk suitable for ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
169 if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
170 seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
171 nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
172
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
173 knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
174 newparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
175 for parent in parents:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
176 if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
177 knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
178 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
179 newparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
180
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
181 ncols = len(seen)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
182 nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
183 nextseen[nodeidx:nodeidx + 1] = newparents
18467
e441657b372b graphmod: don't try to visit nullrev (issue3772)
Bryan O'Sullivan <bryano@fb.com>
parents: 17179
diff changeset
184 edges = [(nodeidx, nextseen.index(p)) for p in knownparents if p != nullrev]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
185
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
186 while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
187 # ascii() only knows how to add or remove a single column between two
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
188 # calls. Nodes with more than two parents break this constraint so we
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
189 # introduce intermediate expansion lines to grow the active node list
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
190 # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
191 edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
192 edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
193 nmorecols = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
194 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
195 char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
196 lines = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
197 nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
198 ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
199 edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
200 del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
201
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
202 if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
203 edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
204 if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
205 edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
206 nmorecols = len(nextseen) - ncols
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
207 seen[:] = nextseen
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
208 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
209
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
210 def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
211 for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
212 if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
213 edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
214
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
215 def _getnodelineedgestail(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
216 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
217 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
218 # Still going in the same non-vertical direction.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
219 if n_columns_diff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
220 start = max(node_index + 1, p_node_index)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
221 tail = ["|", " "] * (start - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
222 tail.extend(["/", " "] * (n_columns - start))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
223 return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
224 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
225 return ["\\", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
226 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
227 return ["|", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
228
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
229 def _drawedges(edges, nodeline, interline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
230 for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
231 if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
232 interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
233 elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
234 interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
235 elif start == end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
236 interline[2 * start] = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
237 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
238 if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
239 continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
240 nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
241 if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
242 (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
243 for i in range(2 * start + 1, 2 * end):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
244 if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
245 nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
246
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
247 def _getpaddingline(ni, n_columns, edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
248 line = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
249 line.extend(["|", " "] * ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
250 if (ni, ni - 1) in edges or (ni, ni) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
251 # (ni, ni - 1) (ni, ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
252 # | | | | | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
253 # +---o | | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
254 # | | c | | c | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
255 # | |/ / | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
256 # | | | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
257 c = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
258 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
259 c = " "
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
260 line.extend([c, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
261 line.extend(["|", " "] * (n_columns - ni - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
262 return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
263
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
264 def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
265 """returns the initial value for the "state" argument to ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
266 return [0, 0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
267
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
268 def ascii(ui, state, type, char, text, coldata):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
269 """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
270
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
271 takes the following arguments (one call per node in the graph):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
272
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
273 - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
274 - Somewhere to keep the needed state in (init to asciistate())
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
275 - Column of the current node in the set of ongoing edges.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
276 - Type indicator of node data, usually 'C' for changesets.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
277 - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
278 - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
279 - List of lines to display as the node's text.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
280 - Edges; a list of (col, next_col) indicating the edges between
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
281 the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
282 - Number of columns (ongoing edges) in the current revision.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
283 - The difference between the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
284 in the next revision and the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
285 in the current revision. That is: -1 means one column removed;
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
286 0 means no columns added or removed; 1 means one column added.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
287 """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
288
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
289 idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
290 assert -2 < coldiff < 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
291 if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
292 # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
293 #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
294 # | | | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
295 # o | | into o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
296 # |X / |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
297 # | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
298 _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
299
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
300 # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
301 #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
302 # | | | | | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
303 # | o---+ into | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
304 # | / / | | | # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
305 # o | | | / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
306 # o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
307 add_padding_line = (len(text) > 2 and coldiff == -1 and
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
308 [x for (x, y) in edges if x + 1 < y])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
309
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
310 # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
311 #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
312 # | | o | | | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
313 # | | |/ / | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
314 # | o | | into | o / / # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
315 # | |/ / | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
316 # o | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
317 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
318
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
319 # nodeline is the line containing the node character (typically o)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
320 nodeline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
321 nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
322
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
323 nodeline.extend(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
324 _getnodelineedgestail(idx, state[1], ncols, coldiff,
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
325 state[0], fix_nodeline_tail))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
326
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
327 # shift_interline is the line containing the non-vertical
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
328 # edges between this entry and the next
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
329 shift_interline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
330 if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
331 n_spaces = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
332 edge_ch = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
333 elif coldiff == 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
334 n_spaces = 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
335 edge_ch = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
336 else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
337 n_spaces = 3
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
338 edge_ch = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
339 shift_interline.extend(n_spaces * [" "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
340 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
341
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
342 # draw edges from the current node to its parents
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
343 _drawedges(edges, nodeline, shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
344
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
345 # lines is the list of all graph lines to print
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
346 lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
347 if add_padding_line:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
348 lines.append(_getpaddingline(idx, ncols, edges))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
349 lines.append(shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
350
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
351 # make sure that there are as many graph lines as there are
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
352 # log strings
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
353 while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
354 text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
355 if len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
356 extra_interline = ["|", " "] * (ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
357 while len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
358 lines.append(extra_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
359
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
360 # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
361 indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
362 for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
363 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
364 ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
365
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
366 # ... and start over
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
367 state[0] = coldiff
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
368 state[1] = idx