##// END OF EJS Templates
graphlog: simplify ascii drawing to process one cset at a time
Dirkjan Ochtman -
r9371:571a7acb default
parent child Browse files
Show More
@@ -100,11 +100,13 b' def get_padding_line(ni, n_columns, edge'
100 line.extend(["|", " "] * (n_columns - ni - 1))
100 line.extend(["|", " "] * (n_columns - ni - 1))
101 return line
101 return line
102
102
103 def ascii(ui, dag):
103 def ascii(ui, base, type, char, text, coldata):
104 """prints an ASCII graph of the DAG
104 """prints an ASCII graph of the DAG
105
105
106 dag is a generator that emits tuples with the following elements:
106 takes the following arguments (one call per node in the graph):
107
107
108 - ui to write to
109 - A list we can keep the needed state in
108 - Column of the current node in the set of ongoing edges.
110 - Column of the current node in the set of ongoing edges.
109 - Type indicator of node data == ASCIIDATA.
111 - Type indicator of node data == ASCIIDATA.
110 - Payload: (char, lines):
112 - Payload: (char, lines):
@@ -119,89 +121,86 b' def ascii(ui, dag):'
119 0 means no columns added or removed; 1 means one column added.
121 0 means no columns added or removed; 1 means one column added.
120 """
122 """
121
123
122 base = [0, 0]
124 idx, edges, ncols, coldiff = coldata
123 for idx, type, (char, text), edges, ncols, coldiff in dag:
125 assert -2 < coldiff < 2
124
126 if coldiff == -1:
125 assert -2 < coldiff < 2
127 # Transform
126 if coldiff == -1:
127 # Transform
128 #
129 # | | | | | |
130 # o | | into o---+
131 # |X / |/ /
132 # | | | |
133 fix_long_right_edges(edges)
134
135 # add_padding_line says whether to rewrite
136 #
128 #
137 # | | | | | | | |
129 # | | | | | |
138 # | o---+ into | o---+
130 # o | | into o---+
139 # | / / | | | # <--- padding line
131 # |X / |/ /
140 # o | | | / /
132 # | | | |
141 # o | |
133 fix_long_right_edges(edges)
142 add_padding_line = (len(text) > 2 and
134
143 coldiff == -1 and
135 # add_padding_line says whether to rewrite
144 [x for (x, y) in edges if x + 1 < y])
136 #
137 # | | | | | | | |
138 # | o---+ into | o---+
139 # | / / | | | # <--- padding line
140 # o | | | / /
141 # o | |
142 add_padding_line = (len(text) > 2 and coldiff == -1 and
143 [x for (x, y) in edges if x + 1 < y])
145
144
146 # fix_nodeline_tail says whether to rewrite
145 # fix_nodeline_tail says whether to rewrite
147 #
146 #
148 # | | o | | | | o | |
147 # | | o | | | | o | |
149 # | | |/ / | | |/ /
148 # | | |/ / | | |/ /
150 # | o | | into | o / / # <--- fixed nodeline tail
149 # | o | | into | o / / # <--- fixed nodeline tail
151 # | |/ / | |/ /
150 # | |/ / | |/ /
152 # o | | o | |
151 # o | | o | |
153 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
152 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
154
153
155 # nodeline is the line containing the node character (typically o)
154 # nodeline is the line containing the node character (typically o)
156 nodeline = ["|", " "] * idx
155 nodeline = ["|", " "] * idx
157 nodeline.extend([char, " "])
156 nodeline.extend([char, " "])
158
157
159 nodeline.extend(
158 nodeline.extend(
160 get_nodeline_edges_tail(idx, base[1], ncols, coldiff,
159 get_nodeline_edges_tail(idx, base[1], ncols, coldiff,
161 base[0], fix_nodeline_tail))
160 base[0], fix_nodeline_tail))
162
161
163 # shift_interline is the line containing the non-vertical
162 # shift_interline is the line containing the non-vertical
164 # edges between this entry and the next
163 # edges between this entry and the next
165 shift_interline = ["|", " "] * idx
164 shift_interline = ["|", " "] * idx
166 if coldiff == -1:
165 if coldiff == -1:
167 n_spaces = 1
166 n_spaces = 1
168 edge_ch = "/"
167 edge_ch = "/"
169 elif coldiff == 0:
168 elif coldiff == 0:
170 n_spaces = 2
169 n_spaces = 2
171 edge_ch = "|"
170 edge_ch = "|"
172 else:
171 else:
173 n_spaces = 3
172 n_spaces = 3
174 edge_ch = "\\"
173 edge_ch = "\\"
175 shift_interline.extend(n_spaces * [" "])
174 shift_interline.extend(n_spaces * [" "])
176 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
175 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
177
176
178 # draw edges from the current node to its parents
177 # draw edges from the current node to its parents
179 draw_edges(edges, nodeline, shift_interline)
178 draw_edges(edges, nodeline, shift_interline)
180
179
181 # lines is the list of all graph lines to print
180 # lines is the list of all graph lines to print
182 lines = [nodeline]
181 lines = [nodeline]
183 if add_padding_line:
182 if add_padding_line:
184 lines.append(get_padding_line(idx, ncols, edges))
183 lines.append(get_padding_line(idx, ncols, edges))
185 lines.append(shift_interline)
184 lines.append(shift_interline)
186
185
187 # make sure that there are as many graph lines as there are
186 # make sure that there are as many graph lines as there are
188 # log strings
187 # log strings
189 while len(text) < len(lines):
188 while len(text) < len(lines):
190 text.append("")
189 text.append("")
191 if len(lines) < len(text):
190 if len(lines) < len(text):
192 extra_interline = ["|", " "] * (ncols + coldiff)
191 extra_interline = ["|", " "] * (ncols + coldiff)
193 while len(lines) < len(text):
192 while len(lines) < len(text):
194 lines.append(extra_interline)
193 lines.append(extra_interline)
195
194
196 # print lines
195 # print lines
197 indentation_level = max(ncols, ncols + coldiff)
196 indentation_level = max(ncols, ncols + coldiff)
198 for (line, logstr) in zip(lines, text):
197 for (line, logstr) in zip(lines, text):
199 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
198 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
200 ui.write(ln.rstrip() + '\n')
199 ui.write(ln.rstrip() + '\n')
201
200
202 # ... and start over
201 # ... and start over
203 base[0] = coldiff
202 base[0] = coldiff
204 base[1] = idx
203 base[1] = idx
205
204
206 def get_revs(repo, rev_opt):
205 def get_revs(repo, rev_opt):
207 if rev_opt:
206 if rev_opt:
@@ -217,14 +216,13 b' def check_unsupported_flags(opts):'
217 if op in opts and opts[op]:
216 if op in opts and opts[op]:
218 raise util.Abort(_("--graph option is incompatible with --%s") % op)
217 raise util.Abort(_("--graph option is incompatible with --%s") % op)
219
218
220 def generate(dag, displayer, showparents, edgefn):
219 def generate(ui, dag, displayer, showparents, edgefn):
221 seen = []
220 seen, base = [], [0, 0]
222 for rev, type, ctx, parents in dag:
221 for rev, type, ctx, parents in dag:
223 char = ctx.node() in showparents and '@' or 'o'
222 char = ctx.node() in showparents and '@' or 'o'
224 displayer.show(ctx)
223 displayer.show(ctx)
225 lines = displayer.hunk.pop(rev).split('\n')[:-1]
224 lines = displayer.hunk.pop(rev).split('\n')[:-1]
226 cols = edgefn(seen, rev, parents)
225 ascii(ui, base, type, char, lines, edgefn(seen, rev, parents))
227 yield cols[0], type, (char, lines), cols[1], cols[2], cols[3]
228
226
229 def graphlog(ui, repo, path=None, **opts):
227 def graphlog(ui, repo, path=None, **opts):
230 """show revision history alongside an ASCII revision graph
228 """show revision history alongside an ASCII revision graph
@@ -252,8 +250,7 b' def graphlog(ui, repo, path=None, **opts'
252
250
253 displayer = show_changeset(ui, repo, opts, buffered=True)
251 displayer = show_changeset(ui, repo, opts, buffered=True)
254 showparents = [ctx.node() for ctx in repo[None].parents()]
252 showparents = [ctx.node() for ctx in repo[None].parents()]
255 gen = generate(revdag, displayer, showparents, asciiedges)
253 generate(ui, revdag, displayer, showparents, asciiedges)
256 ascii(ui, gen)
257
254
258 def graphrevs(repo, nodes, opts):
255 def graphrevs(repo, nodes, opts):
259 limit = cmdutil.loglimit(opts)
256 limit = cmdutil.loglimit(opts)
@@ -289,8 +286,7 b' def goutgoing(ui, repo, dest=None, **opt'
289 revdag = graphrevs(repo, o, opts)
286 revdag = graphrevs(repo, o, opts)
290 displayer = show_changeset(ui, repo, opts, buffered=True)
287 displayer = show_changeset(ui, repo, opts, buffered=True)
291 showparents = [ctx.node() for ctx in repo[None].parents()]
288 showparents = [ctx.node() for ctx in repo[None].parents()]
292 gen = generate(revdag, displayer, showparents, asciiedges)
289 generate(ui, revdag, displayer, showparents, asciiedges)
293 ascii(ui, gen)
294
290
295 def gincoming(ui, repo, source="default", **opts):
291 def gincoming(ui, repo, source="default", **opts):
296 """show the incoming changesets alongside an ASCII revision graph
292 """show the incoming changesets alongside an ASCII revision graph
@@ -340,8 +336,7 b' def gincoming(ui, repo, source="default"'
340 revdag = graphrevs(other, chlist, opts)
336 revdag = graphrevs(other, chlist, opts)
341 displayer = show_changeset(ui, other, opts, buffered=True)
337 displayer = show_changeset(ui, other, opts, buffered=True)
342 showparents = [ctx.node() for ctx in repo[None].parents()]
338 showparents = [ctx.node() for ctx in repo[None].parents()]
343 gen = generate(revdag, displayer, showparents, asciiedges)
339 generate(ui, revdag, displayer, showparents, asciiedges)
344 ascii(ui, gen)
345
340
346 finally:
341 finally:
347 if hasattr(other, 'close'):
342 if hasattr(other, 'close'):
General Comments 0
You need to be logged in to leave comments. Login now