Mercurial > public > mercurial-scm > hg
comparison hgext/graphlog.py @ 16405:17deb6bbfbab
graphlog: refactor revset() to return revisions
When --follow and --rev are passed, --follow actual behaviour depends on the
input revision sequence defined by --rev. If --rev is not passed, the default
revision sequence depends on the presence of --follow. It means the revision
sequence generation is part of log logic and must be wrapped. The issue
described above is fixed in following patches.
author | Patrick Mezard <patrick@mezard.eu> |
---|---|
date | Wed, 11 Apr 2012 11:07:30 +0200 |
parents | 0f1e621d3d3b |
children | 4aa4f50c52b9 |
comparison
equal
deleted
inserted
replaced
16404:9fca5b056c0a | 16405:17deb6bbfbab |
---|---|
269 populate() | 269 populate() |
270 return scmutil.match(wctx, fcache.get(rev, []), default='path') | 270 return scmutil.match(wctx, fcache.get(rev, []), default='path') |
271 | 271 |
272 return filematcher | 272 return filematcher |
273 | 273 |
274 def revset(repo, pats, opts): | 274 def _makelogrevset(repo, pats, opts, revs): |
275 """Return (expr, filematcher) where expr is a revset string built | 275 """Return (expr, filematcher) where expr is a revset string built |
276 log options and file patterns, or None. Note that --rev options | 276 from log options and file patterns or None. If --stat or --patch |
277 are ignored when building expr because we do not know if they are | 277 are not passed filematcher is None. Otherwise it is a callable |
278 proper revsets or legacy expressions like a 'foo-bar' tags. If | 278 taking a revision number and returning a match objects filtering |
279 --stat or --patch are not passed filematcher is None. Otherwise it | 279 the files to be detailed when displaying the revision. |
280 a a callable taking a revision number and returning a match | |
281 objects filtering the files to be detailed when displaying the | |
282 revision. | |
283 """ | 280 """ |
284 opt2revset = { | 281 opt2revset = { |
285 'follow': ('follow()', None), | 282 'follow': ('follow()', None), |
286 'follow_first': ('_followfirst()', None), | 283 'follow_first': ('_followfirst()', None), |
287 'no_merges': ('not merge()', None), | 284 'no_merges': ('not merge()', None), |
296 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '), | 293 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '), |
297 'user': ('user(%(val)r)', ' or '), | 294 'user': ('user(%(val)r)', ' or '), |
298 } | 295 } |
299 | 296 |
300 opts = dict(opts) | 297 opts = dict(opts) |
301 # branch and only_branch are really aliases and must be handled at | 298 # follow or not follow? |
302 # the same time | |
303 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', []) | |
304 follow = opts.get('follow') or opts.get('follow_first') | 299 follow = opts.get('follow') or opts.get('follow_first') |
305 followfirst = opts.get('follow_first') | 300 followfirst = opts.get('follow_first') |
306 if 'follow' in opts: | 301 if 'follow' in opts: |
307 del opts['follow'] | 302 del opts['follow'] |
308 if 'follow_first' in opts: | 303 if 'follow_first' in opts: |
309 del opts['follow_first'] | 304 del opts['follow_first'] |
305 | |
306 # branch and only_branch are really aliases and must be handled at | |
307 # the same time | |
308 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', []) | |
310 # pats/include/exclude are passed to match.match() directly in | 309 # pats/include/exclude are passed to match.match() directly in |
311 # _matchfile() revset but walkchangerevs() builds its matcher with | 310 # _matchfile() revset but walkchangerevs() builds its matcher with |
312 # scmutil.match(). The difference is input pats are globbed on | 311 # scmutil.match(). The difference is input pats are globbed on |
313 # platforms without shell expansion (windows). | 312 # platforms without shell expansion (windows). |
314 pctx = repo[None] | 313 pctx = repo[None] |
390 revset = '(' + ' and '.join(revset) + ')' | 389 revset = '(' + ' and '.join(revset) + ')' |
391 else: | 390 else: |
392 revset = None | 391 revset = None |
393 return revset, filematcher | 392 return revset, filematcher |
394 | 393 |
394 def getlogrevs(repo, pats, opts): | |
395 """Return (revs, expr, filematcher) where revs is a list of | |
396 revision numbers, expr is a revset string built from log options | |
397 and file patterns or None, and used to filter 'revs'. If --stat or | |
398 --patch are not passed filematcher is None. Otherwise it is a | |
399 callable taking a revision number and returning a match objects | |
400 filtering the files to be detailed when displaying the revision. | |
401 """ | |
402 if not len(repo): | |
403 return [], None, None | |
404 if opts.get('rev'): | |
405 revs = scmutil.revrange(repo, opts['rev']) | |
406 else: | |
407 revs = range(len(repo)) | |
408 if not revs: | |
409 return [], None, None | |
410 expr, filematcher = _makelogrevset(repo, pats, opts, revs) | |
411 if expr: | |
412 revs = revsetmod.match(repo.ui, expr)(repo, revs) | |
413 return revs, expr, filematcher | |
414 | |
395 def generate(ui, dag, displayer, showparents, edgefn, getrenamed=None, | 415 def generate(ui, dag, displayer, showparents, edgefn, getrenamed=None, |
396 filematcher=None): | 416 filematcher=None): |
397 seen, state = [], asciistate() | 417 seen, state = [], asciistate() |
398 for rev, type, ctx, parents in dag: | 418 for rev, type, ctx, parents in dag: |
399 char = ctx.node() in showparents and '@' or 'o' | 419 char = ctx.node() in showparents and '@' or 'o' |
432 directory. | 452 directory. |
433 """ | 453 """ |
434 | 454 |
435 check_unsupported_flags(pats, opts) | 455 check_unsupported_flags(pats, opts) |
436 | 456 |
437 expr, filematcher = revset(repo, pats, opts) | 457 revs, expr, filematcher = getlogrevs(repo, pats, opts) |
438 if opts.get('rev'): | |
439 revs = scmutil.revrange(repo, opts['rev']) | |
440 else: | |
441 revs = range(len(repo)) | |
442 if expr: | |
443 revs = revsetmod.match(repo.ui, expr)(repo, revs) | |
444 revs = sorted(revs, reverse=1) | 458 revs = sorted(revs, reverse=1) |
445 limit = cmdutil.loglimit(opts) | 459 limit = cmdutil.loglimit(opts) |
446 if limit is not None: | 460 if limit is not None: |
447 revs = revs[:limit] | 461 revs = revs[:limit] |
448 revdag = graphmod.dagwalker(repo, revs) | 462 revdag = graphmod.dagwalker(repo, revs) |