196 revs = revrange(repo, rev_opt) |
196 revs = revrange(repo, rev_opt) |
197 return (max(revs), min(revs)) |
197 return (max(revs), min(revs)) |
198 else: |
198 else: |
199 return (len(repo) - 1, 0) |
199 return (len(repo) - 1, 0) |
200 |
200 |
201 def graphlog(ui, repo, path=None, **opts): |
201 def ascii(ui, grapher): |
202 """show revision history alongside an ASCII revision graph |
202 """prints an ASCII graph of the DAG returned by the grapher |
203 |
203 |
204 Print a revision history alongside a revision graph drawn with |
204 grapher is a generator that emits tuples with the following elements: |
205 ASCII characters. |
205 |
206 |
206 - Character to use as node's symbol. |
207 Nodes printed as an @ character are parents of the working |
207 - List of lines to display as the node's text. |
208 directory. |
208 - Column of the current node in the set of ongoing edges. |
|
209 - Edges; a list of (col, next_col) indicating the edges between |
|
210 the current node and its parents. |
|
211 - Number of columns (ongoing edges) in the current revision. |
|
212 - The difference between the number of columns (ongoing edges) |
|
213 in the next revision and the number of columns (ongoing edges) |
|
214 in the current revision. That is: -1 means one column removed; |
|
215 0 means no columns added or removed; 1 means one column added. |
209 """ |
216 """ |
210 |
|
211 limit = get_limit(opts["limit"]) |
|
212 (start_rev, stop_rev) = get_revs(repo, opts["rev"]) |
|
213 stop_rev = max(stop_rev, start_rev - limit + 1) |
|
214 if start_rev == nullrev: |
|
215 return |
|
216 cs_printer = show_changeset(ui, repo, opts) |
|
217 if path: |
|
218 path = canonpath(repo.root, os.getcwd(), path) |
|
219 if path: |
|
220 grapher = filelog_grapher(repo, path, start_rev, stop_rev) |
|
221 else: |
|
222 grapher = revision_grapher(repo, start_rev, stop_rev) |
|
223 repo_parents = repo.dirstate.parents() |
|
224 prev_n_columns_diff = 0 |
217 prev_n_columns_diff = 0 |
225 prev_node_index = 0 |
218 prev_node_index = 0 |
226 |
219 for (node_ch, node_lines, node_index, edges, n_columns, n_columns_diff) in grapher: |
227 for (rev, node, node_index, edges, n_columns, n_columns_diff) in grapher: |
|
228 # node_lines is the list of all text lines to draw alongside the graph |
220 # node_lines is the list of all text lines to draw alongside the graph |
229 ui.pushbuffer() |
|
230 cs_printer.show(rev, node) |
|
231 node_lines = ui.popbuffer().split("\n")[:-1] |
|
232 |
221 |
233 if n_columns_diff == -1: |
222 if n_columns_diff == -1: |
234 # Transform |
223 # Transform |
235 # |
224 # |
236 # | | | | | | |
225 # | | | | | | |
259 # o | | o | | |
248 # o | | o | | |
260 fix_nodeline_tail = len(node_lines) <= 2 and not add_padding_line |
249 fix_nodeline_tail = len(node_lines) <= 2 and not add_padding_line |
261 |
250 |
262 # nodeline is the line containing the node character (typically o) |
251 # nodeline is the line containing the node character (typically o) |
263 nodeline = ["|", " "] * node_index |
252 nodeline = ["|", " "] * node_index |
264 if node in repo_parents: |
|
265 node_ch = "@" |
|
266 else: |
|
267 node_ch = "o" |
|
268 nodeline.extend([node_ch, " "]) |
253 nodeline.extend([node_ch, " "]) |
269 |
254 |
270 nodeline.extend( |
255 nodeline.extend( |
271 get_nodeline_edges_tail( |
256 get_nodeline_edges_tail( |
272 node_index, prev_node_index, n_columns, n_columns_diff, |
257 node_index, prev_node_index, n_columns, n_columns_diff, |
312 |
297 |
313 # ... and start over |
298 # ... and start over |
314 prev_node_index = node_index |
299 prev_node_index = node_index |
315 prev_n_columns_diff = n_columns_diff |
300 prev_n_columns_diff = n_columns_diff |
316 |
301 |
|
302 def graphlog(ui, repo, path=None, **opts): |
|
303 """show revision history alongside an ASCII revision graph |
|
304 |
|
305 Print a revision history alongside a revision graph drawn with |
|
306 ASCII characters. |
|
307 |
|
308 Nodes printed as an @ character are parents of the working |
|
309 directory. |
|
310 """ |
|
311 |
|
312 limit = get_limit(opts["limit"]) |
|
313 (start_rev, stop_rev) = get_revs(repo, opts["rev"]) |
|
314 stop_rev = max(stop_rev, start_rev - limit + 1) |
|
315 if start_rev == nullrev: |
|
316 return |
|
317 if path: |
|
318 path = canonpath(repo.root, os.getcwd(), path) |
|
319 if path: |
|
320 revgrapher = filelog_grapher(repo, path, start_rev, stop_rev) |
|
321 else: |
|
322 revgrapher = revision_grapher(repo, start_rev, stop_rev) |
|
323 |
|
324 repo_parents = repo.dirstate.parents() |
|
325 cs_printer = show_changeset(ui, repo, opts) |
|
326 def grapher(): |
|
327 for (rev, node, node_index, edges, n_columns, n_columns_diff) in revgrapher: |
|
328 # log_strings is the list of all log strings to draw alongside |
|
329 # the graph. |
|
330 ui.pushbuffer() |
|
331 cs_printer.show(rev, node) |
|
332 log_strings = ui.popbuffer().split("\n")[:-1] |
|
333 if node in repo_parents: |
|
334 node_ch = "@" |
|
335 else: |
|
336 node_ch = "o" |
|
337 yield (node_ch, log_strings, node_index, edges, n_columns, n_columns_diff) |
|
338 |
|
339 ascii(ui, grapher()) |
|
340 |
317 cmdtable = { |
341 cmdtable = { |
318 "glog": |
342 "glog": |
319 (graphlog, |
343 (graphlog, |
320 [('l', 'limit', '', _('limit number of changes displayed')), |
344 [('l', 'limit', '', _('limit number of changes displayed')), |
321 ('p', 'patch', False, _('show patch')), |
345 ('p', 'patch', False, _('show patch')), |