##// END OF EJS Templates
graphlog: mark --branch as incompatible with --graph...
Martin Geisler -
r11776:13921a1a stable
parent child Browse files
Show More
@@ -1,382 +1,382 b''
1 # ASCII graph log extension for Mercurial
1 # ASCII graph log extension for Mercurial
2 #
2 #
3 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
3 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''command to view revision graphs from a shell
8 '''command to view revision graphs from a shell
9
9
10 This extension adds a --graph option to the incoming, outgoing and log
10 This extension adds a --graph option to the incoming, outgoing and log
11 commands. When this options is given, an ASCII representation of the
11 commands. When this options is given, an ASCII representation of the
12 revision graph is also shown.
12 revision graph is also shown.
13 '''
13 '''
14
14
15 import os
15 import os
16 from mercurial.cmdutil import revrange, show_changeset
16 from mercurial.cmdutil import revrange, show_changeset
17 from mercurial.commands import templateopts
17 from mercurial.commands import templateopts
18 from mercurial.i18n import _
18 from mercurial.i18n import _
19 from mercurial.node import nullrev
19 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, discovery
21 from mercurial import hg, url, util, graphmod, discovery
22
22
23 ASCIIDATA = 'ASC'
23 ASCIIDATA = 'ASC'
24
24
25 def asciiedges(seen, rev, parents):
25 def asciiedges(seen, rev, parents):
26 """adds edge info to changelog DAG walk suitable for ascii()"""
26 """adds edge info to changelog DAG walk suitable for ascii()"""
27 if rev not in seen:
27 if rev not in seen:
28 seen.append(rev)
28 seen.append(rev)
29 nodeidx = seen.index(rev)
29 nodeidx = seen.index(rev)
30
30
31 knownparents = []
31 knownparents = []
32 newparents = []
32 newparents = []
33 for parent in parents:
33 for parent in parents:
34 if parent in seen:
34 if parent in seen:
35 knownparents.append(parent)
35 knownparents.append(parent)
36 else:
36 else:
37 newparents.append(parent)
37 newparents.append(parent)
38
38
39 ncols = len(seen)
39 ncols = len(seen)
40 seen[nodeidx:nodeidx + 1] = newparents
40 seen[nodeidx:nodeidx + 1] = newparents
41 edges = [(nodeidx, seen.index(p)) for p in knownparents]
41 edges = [(nodeidx, seen.index(p)) for p in knownparents]
42
42
43 if len(newparents) > 0:
43 if len(newparents) > 0:
44 edges.append((nodeidx, nodeidx))
44 edges.append((nodeidx, nodeidx))
45 if len(newparents) > 1:
45 if len(newparents) > 1:
46 edges.append((nodeidx, nodeidx + 1))
46 edges.append((nodeidx, nodeidx + 1))
47
47
48 nmorecols = len(seen) - ncols
48 nmorecols = len(seen) - ncols
49 return nodeidx, edges, ncols, nmorecols
49 return nodeidx, edges, ncols, nmorecols
50
50
51 def fix_long_right_edges(edges):
51 def fix_long_right_edges(edges):
52 for (i, (start, end)) in enumerate(edges):
52 for (i, (start, end)) in enumerate(edges):
53 if end > start:
53 if end > start:
54 edges[i] = (start, end + 1)
54 edges[i] = (start, end + 1)
55
55
56 def get_nodeline_edges_tail(
56 def get_nodeline_edges_tail(
57 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
57 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
58 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
58 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
59 # Still going in the same non-vertical direction.
59 # Still going in the same non-vertical direction.
60 if n_columns_diff == -1:
60 if n_columns_diff == -1:
61 start = max(node_index + 1, p_node_index)
61 start = max(node_index + 1, p_node_index)
62 tail = ["|", " "] * (start - node_index - 1)
62 tail = ["|", " "] * (start - node_index - 1)
63 tail.extend(["/", " "] * (n_columns - start))
63 tail.extend(["/", " "] * (n_columns - start))
64 return tail
64 return tail
65 else:
65 else:
66 return ["\\", " "] * (n_columns - node_index - 1)
66 return ["\\", " "] * (n_columns - node_index - 1)
67 else:
67 else:
68 return ["|", " "] * (n_columns - node_index - 1)
68 return ["|", " "] * (n_columns - node_index - 1)
69
69
70 def draw_edges(edges, nodeline, interline):
70 def draw_edges(edges, nodeline, interline):
71 for (start, end) in edges:
71 for (start, end) in edges:
72 if start == end + 1:
72 if start == end + 1:
73 interline[2 * end + 1] = "/"
73 interline[2 * end + 1] = "/"
74 elif start == end - 1:
74 elif start == end - 1:
75 interline[2 * start + 1] = "\\"
75 interline[2 * start + 1] = "\\"
76 elif start == end:
76 elif start == end:
77 interline[2 * start] = "|"
77 interline[2 * start] = "|"
78 else:
78 else:
79 nodeline[2 * end] = "+"
79 nodeline[2 * end] = "+"
80 if start > end:
80 if start > end:
81 (start, end) = (end, start)
81 (start, end) = (end, start)
82 for i in range(2 * start + 1, 2 * end):
82 for i in range(2 * start + 1, 2 * end):
83 if nodeline[i] != "+":
83 if nodeline[i] != "+":
84 nodeline[i] = "-"
84 nodeline[i] = "-"
85
85
86 def get_padding_line(ni, n_columns, edges):
86 def get_padding_line(ni, n_columns, edges):
87 line = []
87 line = []
88 line.extend(["|", " "] * ni)
88 line.extend(["|", " "] * ni)
89 if (ni, ni - 1) in edges or (ni, ni) in edges:
89 if (ni, ni - 1) in edges or (ni, ni) in edges:
90 # (ni, ni - 1) (ni, ni)
90 # (ni, ni - 1) (ni, ni)
91 # | | | | | | | |
91 # | | | | | | | |
92 # +---o | | o---+
92 # +---o | | o---+
93 # | | c | | c | |
93 # | | c | | c | |
94 # | |/ / | |/ /
94 # | |/ / | |/ /
95 # | | | | | |
95 # | | | | | |
96 c = "|"
96 c = "|"
97 else:
97 else:
98 c = " "
98 c = " "
99 line.extend([c, " "])
99 line.extend([c, " "])
100 line.extend(["|", " "] * (n_columns - ni - 1))
100 line.extend(["|", " "] * (n_columns - ni - 1))
101 return line
101 return line
102
102
103 def asciistate():
103 def asciistate():
104 """returns the initial value for the "state" argument to ascii()"""
104 """returns the initial value for the "state" argument to ascii()"""
105 return [0, 0]
105 return [0, 0]
106
106
107 def ascii(ui, state, type, char, text, coldata):
107 def ascii(ui, state, type, char, text, coldata):
108 """prints an ASCII graph of the DAG
108 """prints an ASCII graph of the DAG
109
109
110 takes the following arguments (one call per node in the graph):
110 takes the following arguments (one call per node in the graph):
111
111
112 - ui to write to
112 - ui to write to
113 - Somewhere to keep the needed state in (init to asciistate())
113 - Somewhere to keep the needed state in (init to asciistate())
114 - Column of the current node in the set of ongoing edges.
114 - Column of the current node in the set of ongoing edges.
115 - Type indicator of node data == ASCIIDATA.
115 - Type indicator of node data == ASCIIDATA.
116 - Payload: (char, lines):
116 - Payload: (char, lines):
117 - Character to use as node's symbol.
117 - Character to use as node's symbol.
118 - List of lines to display as the node's text.
118 - List of lines to display as the node's text.
119 - Edges; a list of (col, next_col) indicating the edges between
119 - Edges; a list of (col, next_col) indicating the edges between
120 the current node and its parents.
120 the current node and its parents.
121 - Number of columns (ongoing edges) in the current revision.
121 - Number of columns (ongoing edges) in the current revision.
122 - The difference between the number of columns (ongoing edges)
122 - The difference between the number of columns (ongoing edges)
123 in the next revision and the number of columns (ongoing edges)
123 in the next revision and the number of columns (ongoing edges)
124 in the current revision. That is: -1 means one column removed;
124 in the current revision. That is: -1 means one column removed;
125 0 means no columns added or removed; 1 means one column added.
125 0 means no columns added or removed; 1 means one column added.
126 """
126 """
127
127
128 idx, edges, ncols, coldiff = coldata
128 idx, edges, ncols, coldiff = coldata
129 assert -2 < coldiff < 2
129 assert -2 < coldiff < 2
130 if coldiff == -1:
130 if coldiff == -1:
131 # Transform
131 # Transform
132 #
132 #
133 # | | | | | |
133 # | | | | | |
134 # o | | into o---+
134 # o | | into o---+
135 # |X / |/ /
135 # |X / |/ /
136 # | | | |
136 # | | | |
137 fix_long_right_edges(edges)
137 fix_long_right_edges(edges)
138
138
139 # add_padding_line says whether to rewrite
139 # add_padding_line says whether to rewrite
140 #
140 #
141 # | | | | | | | |
141 # | | | | | | | |
142 # | o---+ into | o---+
142 # | o---+ into | o---+
143 # | / / | | | # <--- padding line
143 # | / / | | | # <--- padding line
144 # o | | | / /
144 # o | | | / /
145 # o | |
145 # o | |
146 add_padding_line = (len(text) > 2 and coldiff == -1 and
146 add_padding_line = (len(text) > 2 and coldiff == -1 and
147 [x for (x, y) in edges if x + 1 < y])
147 [x for (x, y) in edges if x + 1 < y])
148
148
149 # fix_nodeline_tail says whether to rewrite
149 # fix_nodeline_tail says whether to rewrite
150 #
150 #
151 # | | o | | | | o | |
151 # | | o | | | | o | |
152 # | | |/ / | | |/ /
152 # | | |/ / | | |/ /
153 # | o | | into | o / / # <--- fixed nodeline tail
153 # | o | | into | o / / # <--- fixed nodeline tail
154 # | |/ / | |/ /
154 # | |/ / | |/ /
155 # o | | o | |
155 # o | | o | |
156 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
156 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
157
157
158 # nodeline is the line containing the node character (typically o)
158 # nodeline is the line containing the node character (typically o)
159 nodeline = ["|", " "] * idx
159 nodeline = ["|", " "] * idx
160 nodeline.extend([char, " "])
160 nodeline.extend([char, " "])
161
161
162 nodeline.extend(
162 nodeline.extend(
163 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
163 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
164 state[0], fix_nodeline_tail))
164 state[0], fix_nodeline_tail))
165
165
166 # shift_interline is the line containing the non-vertical
166 # shift_interline is the line containing the non-vertical
167 # edges between this entry and the next
167 # edges between this entry and the next
168 shift_interline = ["|", " "] * idx
168 shift_interline = ["|", " "] * idx
169 if coldiff == -1:
169 if coldiff == -1:
170 n_spaces = 1
170 n_spaces = 1
171 edge_ch = "/"
171 edge_ch = "/"
172 elif coldiff == 0:
172 elif coldiff == 0:
173 n_spaces = 2
173 n_spaces = 2
174 edge_ch = "|"
174 edge_ch = "|"
175 else:
175 else:
176 n_spaces = 3
176 n_spaces = 3
177 edge_ch = "\\"
177 edge_ch = "\\"
178 shift_interline.extend(n_spaces * [" "])
178 shift_interline.extend(n_spaces * [" "])
179 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
179 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
180
180
181 # draw edges from the current node to its parents
181 # draw edges from the current node to its parents
182 draw_edges(edges, nodeline, shift_interline)
182 draw_edges(edges, nodeline, shift_interline)
183
183
184 # lines is the list of all graph lines to print
184 # lines is the list of all graph lines to print
185 lines = [nodeline]
185 lines = [nodeline]
186 if add_padding_line:
186 if add_padding_line:
187 lines.append(get_padding_line(idx, ncols, edges))
187 lines.append(get_padding_line(idx, ncols, edges))
188 lines.append(shift_interline)
188 lines.append(shift_interline)
189
189
190 # make sure that there are as many graph lines as there are
190 # make sure that there are as many graph lines as there are
191 # log strings
191 # log strings
192 while len(text) < len(lines):
192 while len(text) < len(lines):
193 text.append("")
193 text.append("")
194 if len(lines) < len(text):
194 if len(lines) < len(text):
195 extra_interline = ["|", " "] * (ncols + coldiff)
195 extra_interline = ["|", " "] * (ncols + coldiff)
196 while len(lines) < len(text):
196 while len(lines) < len(text):
197 lines.append(extra_interline)
197 lines.append(extra_interline)
198
198
199 # print lines
199 # print lines
200 indentation_level = max(ncols, ncols + coldiff)
200 indentation_level = max(ncols, ncols + coldiff)
201 for (line, logstr) in zip(lines, text):
201 for (line, logstr) in zip(lines, text):
202 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
202 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
203 ui.write(ln.rstrip() + '\n')
203 ui.write(ln.rstrip() + '\n')
204
204
205 # ... and start over
205 # ... and start over
206 state[0] = coldiff
206 state[0] = coldiff
207 state[1] = idx
207 state[1] = idx
208
208
209 def get_revs(repo, rev_opt):
209 def get_revs(repo, rev_opt):
210 if rev_opt:
210 if rev_opt:
211 revs = revrange(repo, rev_opt)
211 revs = revrange(repo, rev_opt)
212 if len(revs) == 0:
212 if len(revs) == 0:
213 return (nullrev, nullrev)
213 return (nullrev, nullrev)
214 return (max(revs), min(revs))
214 return (max(revs), min(revs))
215 else:
215 else:
216 return (len(repo) - 1, 0)
216 return (len(repo) - 1, 0)
217
217
218 def check_unsupported_flags(opts):
218 def check_unsupported_flags(opts):
219 for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
219 for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
220 "only_merges", "user", "only_branch", "prune", "newest_first",
220 "only_merges", "user", "branch", "only_branch", "prune",
221 "no_merges", "include", "exclude"]:
221 "newest_first", "no_merges", "include", "exclude"]:
222 if op in opts and opts[op]:
222 if op in opts and opts[op]:
223 raise util.Abort(_("--graph option is incompatible with --%s")
223 raise util.Abort(_("--graph option is incompatible with --%s")
224 % op.replace("_", "-"))
224 % op.replace("_", "-"))
225
225
226 def generate(ui, dag, displayer, showparents, edgefn):
226 def generate(ui, dag, displayer, showparents, edgefn):
227 seen, state = [], asciistate()
227 seen, state = [], asciistate()
228 for rev, type, ctx, parents in dag:
228 for rev, type, ctx, parents in dag:
229 char = ctx.node() in showparents and '@' or 'o'
229 char = ctx.node() in showparents and '@' or 'o'
230 displayer.show(ctx)
230 displayer.show(ctx)
231 lines = displayer.hunk.pop(rev).split('\n')[:-1]
231 lines = displayer.hunk.pop(rev).split('\n')[:-1]
232 ascii(ui, state, type, char, lines, edgefn(seen, rev, parents))
232 ascii(ui, state, type, char, lines, edgefn(seen, rev, parents))
233
233
234 def graphlog(ui, repo, path=None, **opts):
234 def graphlog(ui, repo, path=None, **opts):
235 """show revision history alongside an ASCII revision graph
235 """show revision history alongside an ASCII revision graph
236
236
237 Print a revision history alongside a revision graph drawn with
237 Print a revision history alongside a revision graph drawn with
238 ASCII characters.
238 ASCII characters.
239
239
240 Nodes printed as an @ character are parents of the working
240 Nodes printed as an @ character are parents of the working
241 directory.
241 directory.
242 """
242 """
243
243
244 check_unsupported_flags(opts)
244 check_unsupported_flags(opts)
245 limit = cmdutil.loglimit(opts)
245 limit = cmdutil.loglimit(opts)
246 start, stop = get_revs(repo, opts["rev"])
246 start, stop = get_revs(repo, opts["rev"])
247 if start == nullrev:
247 if start == nullrev:
248 return
248 return
249
249
250 if path:
250 if path:
251 path = util.canonpath(repo.root, os.getcwd(), path)
251 path = util.canonpath(repo.root, os.getcwd(), path)
252 if path: # could be reset in canonpath
252 if path: # could be reset in canonpath
253 revdag = graphmod.filerevs(repo, path, start, stop, limit)
253 revdag = graphmod.filerevs(repo, path, start, stop, limit)
254 else:
254 else:
255 if limit is not None:
255 if limit is not None:
256 stop = max(stop, start - limit + 1)
256 stop = max(stop, start - limit + 1)
257 revdag = graphmod.revisions(repo, start, stop)
257 revdag = graphmod.revisions(repo, start, stop)
258
258
259 displayer = show_changeset(ui, repo, opts, buffered=True)
259 displayer = show_changeset(ui, repo, opts, buffered=True)
260 showparents = [ctx.node() for ctx in repo[None].parents()]
260 showparents = [ctx.node() for ctx in repo[None].parents()]
261 generate(ui, revdag, displayer, showparents, asciiedges)
261 generate(ui, revdag, displayer, showparents, asciiedges)
262
262
263 def graphrevs(repo, nodes, opts):
263 def graphrevs(repo, nodes, opts):
264 limit = cmdutil.loglimit(opts)
264 limit = cmdutil.loglimit(opts)
265 nodes.reverse()
265 nodes.reverse()
266 if limit is not None:
266 if limit is not None:
267 nodes = nodes[:limit]
267 nodes = nodes[:limit]
268 return graphmod.nodes(repo, nodes)
268 return graphmod.nodes(repo, nodes)
269
269
270 def goutgoing(ui, repo, dest=None, **opts):
270 def goutgoing(ui, repo, dest=None, **opts):
271 """show the outgoing changesets alongside an ASCII revision graph
271 """show the outgoing changesets alongside an ASCII revision graph
272
272
273 Print the outgoing changesets alongside a revision graph drawn with
273 Print the outgoing changesets alongside a revision graph drawn with
274 ASCII characters.
274 ASCII characters.
275
275
276 Nodes printed as an @ character are parents of the working
276 Nodes printed as an @ character are parents of the working
277 directory.
277 directory.
278 """
278 """
279
279
280 check_unsupported_flags(opts)
280 check_unsupported_flags(opts)
281 dest = ui.expandpath(dest or 'default-push', dest or 'default')
281 dest = ui.expandpath(dest or 'default-push', dest or 'default')
282 dest, branches = hg.parseurl(dest, opts.get('branch'))
282 dest, branches = hg.parseurl(dest, opts.get('branch'))
283 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
283 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
284 other = hg.repository(hg.remoteui(ui, opts), dest)
284 other = hg.repository(hg.remoteui(ui, opts), dest)
285 if revs:
285 if revs:
286 revs = [repo.lookup(rev) for rev in revs]
286 revs = [repo.lookup(rev) for rev in revs]
287 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
287 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
288 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
288 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
289 if not o:
289 if not o:
290 ui.status(_("no changes found\n"))
290 ui.status(_("no changes found\n"))
291 return
291 return
292
292
293 o = repo.changelog.nodesbetween(o, revs)[0]
293 o = repo.changelog.nodesbetween(o, revs)[0]
294 revdag = graphrevs(repo, o, opts)
294 revdag = graphrevs(repo, o, opts)
295 displayer = show_changeset(ui, repo, opts, buffered=True)
295 displayer = show_changeset(ui, repo, opts, buffered=True)
296 showparents = [ctx.node() for ctx in repo[None].parents()]
296 showparents = [ctx.node() for ctx in repo[None].parents()]
297 generate(ui, revdag, displayer, showparents, asciiedges)
297 generate(ui, revdag, displayer, showparents, asciiedges)
298
298
299 def gincoming(ui, repo, source="default", **opts):
299 def gincoming(ui, repo, source="default", **opts):
300 """show the incoming changesets alongside an ASCII revision graph
300 """show the incoming changesets alongside an ASCII revision graph
301
301
302 Print the incoming changesets alongside a revision graph drawn with
302 Print the incoming changesets alongside a revision graph drawn with
303 ASCII characters.
303 ASCII characters.
304
304
305 Nodes printed as an @ character are parents of the working
305 Nodes printed as an @ character are parents of the working
306 directory.
306 directory.
307 """
307 """
308
308
309 check_unsupported_flags(opts)
309 check_unsupported_flags(opts)
310 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
310 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
311 other = hg.repository(hg.remoteui(repo, opts), source)
311 other = hg.repository(hg.remoteui(repo, opts), source)
312 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
312 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
313 ui.status(_('comparing with %s\n') % url.hidepassword(source))
313 ui.status(_('comparing with %s\n') % url.hidepassword(source))
314 if revs:
314 if revs:
315 revs = [other.lookup(rev) for rev in revs]
315 revs = [other.lookup(rev) for rev in revs]
316 incoming = discovery.findincoming(repo, other, heads=revs,
316 incoming = discovery.findincoming(repo, other, heads=revs,
317 force=opts["force"])
317 force=opts["force"])
318 if not incoming:
318 if not incoming:
319 try:
319 try:
320 os.unlink(opts["bundle"])
320 os.unlink(opts["bundle"])
321 except:
321 except:
322 pass
322 pass
323 ui.status(_("no changes found\n"))
323 ui.status(_("no changes found\n"))
324 return
324 return
325
325
326 cleanup = None
326 cleanup = None
327 try:
327 try:
328
328
329 fname = opts["bundle"]
329 fname = opts["bundle"]
330 if fname or not other.local():
330 if fname or not other.local():
331 # create a bundle (uncompressed if other repo is not local)
331 # create a bundle (uncompressed if other repo is not local)
332 if revs is None:
332 if revs is None:
333 cg = other.changegroup(incoming, "incoming")
333 cg = other.changegroup(incoming, "incoming")
334 else:
334 else:
335 cg = other.changegroupsubset(incoming, revs, 'incoming')
335 cg = other.changegroupsubset(incoming, revs, 'incoming')
336 bundletype = other.local() and "HG10BZ" or "HG10UN"
336 bundletype = other.local() and "HG10BZ" or "HG10UN"
337 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
337 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
338 # keep written bundle?
338 # keep written bundle?
339 if opts["bundle"]:
339 if opts["bundle"]:
340 cleanup = None
340 cleanup = None
341 if not other.local():
341 if not other.local():
342 # use the created uncompressed bundlerepo
342 # use the created uncompressed bundlerepo
343 other = bundlerepo.bundlerepository(ui, repo.root, fname)
343 other = bundlerepo.bundlerepository(ui, repo.root, fname)
344
344
345 chlist = other.changelog.nodesbetween(incoming, revs)[0]
345 chlist = other.changelog.nodesbetween(incoming, revs)[0]
346 revdag = graphrevs(other, chlist, opts)
346 revdag = graphrevs(other, chlist, opts)
347 displayer = show_changeset(ui, other, opts, buffered=True)
347 displayer = show_changeset(ui, other, opts, buffered=True)
348 showparents = [ctx.node() for ctx in repo[None].parents()]
348 showparents = [ctx.node() for ctx in repo[None].parents()]
349 generate(ui, revdag, displayer, showparents, asciiedges)
349 generate(ui, revdag, displayer, showparents, asciiedges)
350
350
351 finally:
351 finally:
352 if hasattr(other, 'close'):
352 if hasattr(other, 'close'):
353 other.close()
353 other.close()
354 if cleanup:
354 if cleanup:
355 os.unlink(cleanup)
355 os.unlink(cleanup)
356
356
357 def uisetup(ui):
357 def uisetup(ui):
358 '''Initialize the extension.'''
358 '''Initialize the extension.'''
359 _wrapcmd(ui, 'log', commands.table, graphlog)
359 _wrapcmd(ui, 'log', commands.table, graphlog)
360 _wrapcmd(ui, 'incoming', commands.table, gincoming)
360 _wrapcmd(ui, 'incoming', commands.table, gincoming)
361 _wrapcmd(ui, 'outgoing', commands.table, goutgoing)
361 _wrapcmd(ui, 'outgoing', commands.table, goutgoing)
362
362
363 def _wrapcmd(ui, cmd, table, wrapfn):
363 def _wrapcmd(ui, cmd, table, wrapfn):
364 '''wrap the command'''
364 '''wrap the command'''
365 def graph(orig, *args, **kwargs):
365 def graph(orig, *args, **kwargs):
366 if kwargs['graph']:
366 if kwargs['graph']:
367 return wrapfn(*args, **kwargs)
367 return wrapfn(*args, **kwargs)
368 return orig(*args, **kwargs)
368 return orig(*args, **kwargs)
369 entry = extensions.wrapcommand(table, cmd, graph)
369 entry = extensions.wrapcommand(table, cmd, graph)
370 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
370 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
371
371
372 cmdtable = {
372 cmdtable = {
373 "glog":
373 "glog":
374 (graphlog,
374 (graphlog,
375 [('l', 'limit', '',
375 [('l', 'limit', '',
376 _('limit number of changes displayed'), _('NUM')),
376 _('limit number of changes displayed'), _('NUM')),
377 ('p', 'patch', False, _('show patch')),
377 ('p', 'patch', False, _('show patch')),
378 ('r', 'rev', [],
378 ('r', 'rev', [],
379 _('show the specified revision or range'), _('REV')),
379 _('show the specified revision or range'), _('REV')),
380 ] + templateopts,
380 ] + templateopts,
381 _('hg glog [OPTION]... [FILE]')),
381 _('hg glog [OPTION]... [FILE]')),
382 }
382 }
General Comments 0
You need to be logged in to leave comments. Login now