Mercurial > public > mercurial-scm > hg
comparison hgext/graphlog.py @ 14043:1c1e1232abdc
graphlog: make use of graphmod's revset support
author | Alexander Solovyov <alexander@solovyov.net> |
---|---|
date | Sat, 23 Apr 2011 15:04:15 +0200 |
parents | 9966c95b8c4f |
children | 8670e3694b85 |
comparison
equal
deleted
inserted
replaced
14042:9966c95b8c4f | 14043:1c1e1232abdc |
---|---|
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 | |
16 from mercurial.cmdutil import revrange, show_changeset | 15 from mercurial.cmdutil import revrange, show_changeset |
17 from mercurial.commands import templateopts | 16 from mercurial.commands import templateopts |
18 from mercurial.i18n import _ | 17 from mercurial.i18n import _ |
19 from mercurial.node import nullrev | 18 from mercurial.node import nullrev |
20 from mercurial import cmdutil, commands, extensions | 19 from mercurial import cmdutil, commands, extensions |
214 return (max(revs), min(revs)) | 213 return (max(revs), min(revs)) |
215 else: | 214 else: |
216 return (len(repo) - 1, 0) | 215 return (len(repo) - 1, 0) |
217 | 216 |
218 def check_unsupported_flags(opts): | 217 def check_unsupported_flags(opts): |
219 for op in ["follow", "follow_first", "date", "copies", "keyword", "remove", | 218 for op in ["follow_first", "copies", "newest_first"]: |
220 "only_merges", "user", "branch", "only_branch", "prune", | |
221 "newest_first", "no_merges", "include", "exclude"]: | |
222 if op in opts and opts[op]: | 219 if op in opts and opts[op]: |
223 raise util.Abort(_("--graph option is incompatible with --%s") | 220 raise util.Abort(_("-G/--graph option is incompatible with --%s") |
224 % op.replace("_", "-")) | 221 % op.replace("_", "-")) |
222 | |
223 def revset(pats, opts): | |
224 """Return revset str built of revisions, log options and file patterns. | |
225 """ | |
226 opt2revset = dict(only_merges='merge', | |
227 only_branch='branch', | |
228 no_merges='not merge', | |
229 include='file', | |
230 exclude='not file', | |
231 prune='not follow') | |
232 revset = [] | |
233 for op, val in opts.iteritems(): | |
234 if not val: | |
235 continue | |
236 revop = opt2revset.get(op, op) | |
237 if op in ('follow', 'only_merges', 'no_merges'): | |
238 revset.append('%s()' % revop) | |
239 elif op in ("date", "keyword", "remove", "user", "branch", | |
240 "only_branch", "prune"): | |
241 revset.append('%s(%s)' % (op, val)) | |
242 elif op in ('include', 'exclude'): | |
243 for f in val: | |
244 revset.append('%s(%r)' % (op, f)) | |
245 elif op == 'rev': | |
246 revset.extend(val) | |
247 | |
248 for path in pats: | |
249 revset.append('file(%r)' % path) | |
250 | |
251 revset = ' and '.join(revset) or 'all()' | |
252 # we want reverted revset to build graph | |
253 revset = 'reverse(%s)' % revset | |
254 if opts['limit']: | |
255 revset = 'limit(%s, %s)' % (revset, opts['limit']) | |
256 return revset | |
225 | 257 |
226 def generate(ui, dag, displayer, showparents, edgefn): | 258 def generate(ui, dag, displayer, showparents, edgefn): |
227 seen, state = [], asciistate() | 259 seen, state = [], asciistate() |
228 for rev, type, ctx, parents in dag: | 260 for rev, type, ctx, parents in dag: |
229 char = ctx.node() in showparents and '@' or 'o' | 261 char = ctx.node() in showparents and '@' or 'o' |
231 lines = displayer.hunk.pop(rev).split('\n')[:-1] | 263 lines = displayer.hunk.pop(rev).split('\n')[:-1] |
232 displayer.flush(rev) | 264 displayer.flush(rev) |
233 ascii(ui, state, type, char, lines, edgefn(seen, rev, parents)) | 265 ascii(ui, state, type, char, lines, edgefn(seen, rev, parents)) |
234 displayer.close() | 266 displayer.close() |
235 | 267 |
236 def graphlog(ui, repo, path=None, **opts): | 268 def graphlog(ui, repo, *pats, **opts): |
237 """show revision history alongside an ASCII revision graph | 269 """show revision history alongside an ASCII revision graph |
238 | 270 |
239 Print a revision history alongside a revision graph drawn with | 271 Print a revision history alongside a revision graph drawn with |
240 ASCII characters. | 272 ASCII characters. |
241 | 273 |
242 Nodes printed as an @ character are parents of the working | 274 Nodes printed as an @ character are parents of the working |
243 directory. | 275 directory. |
244 """ | 276 """ |
245 | 277 |
246 check_unsupported_flags(opts) | 278 check_unsupported_flags(opts) |
247 limit = cmdutil.loglimit(opts) | 279 |
248 start, stop = get_revs(repo, opts["rev"]) | 280 revs = revrange(repo, [revset(pats, opts)]) |
249 if start == nullrev: | 281 revdag = graphmod.dagwalker(repo, revs) |
250 return | |
251 | |
252 if path: # could be reset in canonpath | |
253 revdag = graphmod.filerevs(repo, path, start, stop, limit) | |
254 else: | |
255 if limit is not None: | |
256 stop = max(stop, start - limit + 1) | |
257 revdag = graphmod.revisions(repo, start, stop) | |
258 | 282 |
259 displayer = show_changeset(ui, repo, opts, buffered=True) | 283 displayer = show_changeset(ui, repo, opts, buffered=True) |
260 showparents = [ctx.node() for ctx in repo[None].parents()] | 284 showparents = [ctx.node() for ctx in repo[None].parents()] |
261 generate(ui, revdag, displayer, showparents, asciiedges) | 285 generate(ui, revdag, displayer, showparents, asciiedges) |
262 | 286 |
315 | 339 |
316 def _wrapcmd(ui, cmd, table, wrapfn): | 340 def _wrapcmd(ui, cmd, table, wrapfn): |
317 '''wrap the command''' | 341 '''wrap the command''' |
318 def graph(orig, *args, **kwargs): | 342 def graph(orig, *args, **kwargs): |
319 if kwargs['graph']: | 343 if kwargs['graph']: |
320 try: | 344 return wrapfn(*args, **kwargs) |
321 return wrapfn(*args, **kwargs) | |
322 except TypeError, e: | |
323 if len(args) > wrapfn.func_code.co_argcount: | |
324 raise util.Abort(_('--graph option allows at most one file')) | |
325 raise | |
326 return orig(*args, **kwargs) | 345 return orig(*args, **kwargs) |
327 entry = extensions.wrapcommand(table, cmd, graph) | 346 entry = extensions.wrapcommand(table, cmd, graph) |
328 entry[1].append(('G', 'graph', None, _("show the revision DAG"))) | 347 entry[1].append(('G', 'graph', None, _("show the revision DAG"))) |
329 | 348 |
330 cmdtable = { | 349 cmdtable = { |