comparison mercurial/logcmdutil.py @ 35887:572f36e9a780

logcmdutil: drop redundant "log" from function names (API) A few exceptions: - s/loglimit/getlimit/ to avoid name conflict - s/_logrevs/_initialrevs/ to clarify its functionality
author Yuya Nishihara <yuya@tcha.org>
date Sun, 21 Jan 2018 12:48:39 +0900
parents b0014780c7fc
children 64f4a6808704
comparison
equal deleted inserted replaced
35886:b0014780c7fc 35887:572f36e9a780
34 templatekw, 34 templatekw,
35 templater, 35 templater,
36 util, 36 util,
37 ) 37 )
38 38
39 def loglimit(opts): 39 def getlimit(opts):
40 """get the log limit according to option -l/--limit""" 40 """get the log limit according to option -l/--limit"""
41 limit = opts.get('limit') 41 limit = opts.get('limit')
42 if limit: 42 if limit:
43 try: 43 try:
44 limit = int(limit) 44 limit = int(limit)
389 class changesettemplater(changesetprinter): 389 class changesettemplater(changesetprinter):
390 '''format changeset information. 390 '''format changeset information.
391 391
392 Note: there are a variety of convenience functions to build a 392 Note: there are a variety of convenience functions to build a
393 changesettemplater for common cases. See functions such as: 393 changesettemplater for common cases. See functions such as:
394 makelogtemplater, changesetdisplayer, buildcommittemplate, or other 394 maketemplater, changesetdisplayer, buildcommittemplate, or other
395 functions that use changesest_templater. 395 functions that use changesest_templater.
396 ''' 396 '''
397 397
398 # Arguments before "buffered" used to be positional. Consider not 398 # Arguments before "buffered" used to be positional. Consider not
399 # adding/removing arguments before "buffered" to not break callers. 399 # adding/removing arguments before "buffered" to not break callers.
476 if self._parts['footer']: 476 if self._parts['footer']:
477 if not self.footer: 477 if not self.footer:
478 self.footer = templater.stringify( 478 self.footer = templater.stringify(
479 self.t(self._parts['footer'], **props)) 479 self.t(self._parts['footer'], **props))
480 480
481 def logtemplatespec(tmpl, mapfile): 481 def templatespec(tmpl, mapfile):
482 if mapfile: 482 if mapfile:
483 return formatter.templatespec('changeset', tmpl, mapfile) 483 return formatter.templatespec('changeset', tmpl, mapfile)
484 else: 484 else:
485 return formatter.templatespec('', tmpl, None) 485 return formatter.templatespec('', tmpl, None)
486 486
487 def _lookuplogtemplate(ui, tmpl, style): 487 def _lookuptemplate(ui, tmpl, style):
488 """Find the template matching the given template spec or style 488 """Find the template matching the given template spec or style
489 489
490 See formatter.lookuptemplate() for details. 490 See formatter.lookuptemplate() for details.
491 """ 491 """
492 492
493 # ui settings 493 # ui settings
494 if not tmpl and not style: # template are stronger than style 494 if not tmpl and not style: # template are stronger than style
495 tmpl = ui.config('ui', 'logtemplate') 495 tmpl = ui.config('ui', 'logtemplate')
496 if tmpl: 496 if tmpl:
497 return logtemplatespec(templater.unquotestring(tmpl), None) 497 return templatespec(templater.unquotestring(tmpl), None)
498 else: 498 else:
499 style = util.expandpath(ui.config('ui', 'style')) 499 style = util.expandpath(ui.config('ui', 'style'))
500 500
501 if not tmpl and style: 501 if not tmpl and style:
502 mapfile = style 502 mapfile = style
503 if not os.path.split(mapfile)[0]: 503 if not os.path.split(mapfile)[0]:
504 mapname = (templater.templatepath('map-cmdline.' + mapfile) 504 mapname = (templater.templatepath('map-cmdline.' + mapfile)
505 or templater.templatepath(mapfile)) 505 or templater.templatepath(mapfile))
506 if mapname: 506 if mapname:
507 mapfile = mapname 507 mapfile = mapname
508 return logtemplatespec(None, mapfile) 508 return templatespec(None, mapfile)
509 509
510 if not tmpl: 510 if not tmpl:
511 return logtemplatespec(None, None) 511 return templatespec(None, None)
512 512
513 return formatter.lookuptemplate(ui, 'changeset', tmpl) 513 return formatter.lookuptemplate(ui, 'changeset', tmpl)
514 514
515 def makelogtemplater(ui, repo, tmpl, buffered=False): 515 def maketemplater(ui, repo, tmpl, buffered=False):
516 """Create a changesettemplater from a literal template 'tmpl' 516 """Create a changesettemplater from a literal template 'tmpl'
517 byte-string.""" 517 byte-string."""
518 spec = logtemplatespec(tmpl, None) 518 spec = templatespec(tmpl, None)
519 return changesettemplater(ui, repo, spec, buffered=buffered) 519 return changesettemplater(ui, repo, spec, buffered=buffered)
520 520
521 def changesetdisplayer(ui, repo, opts, buffered=False): 521 def changesetdisplayer(ui, repo, opts, buffered=False):
522 """show one changeset using template or regular display. 522 """show one changeset using template or regular display.
523 523
535 match = scmutil.matchall(repo) 535 match = scmutil.matchall(repo)
536 536
537 if opts.get('template') == 'json': 537 if opts.get('template') == 'json':
538 return jsonchangeset(ui, repo, match, opts, buffered) 538 return jsonchangeset(ui, repo, match, opts, buffered)
539 539
540 spec = _lookuplogtemplate(ui, opts.get('template'), opts.get('style')) 540 spec = _lookuptemplate(ui, opts.get('template'), opts.get('style'))
541 541
542 if not spec.ref and not spec.tmpl and not spec.mapfile: 542 if not spec.ref and not spec.tmpl and not spec.mapfile:
543 return changesetprinter(ui, repo, match, opts, buffered) 543 return changesetprinter(ui, repo, match, opts, buffered)
544 544
545 return changesettemplater(ui, repo, spec, match, opts, buffered) 545 return changesettemplater(ui, repo, spec, match, opts, buffered)
546 546
547 def _makelogmatcher(repo, revs, pats, opts): 547 def _makematcher(repo, revs, pats, opts):
548 """Build matcher and expanded patterns from log options 548 """Build matcher and expanded patterns from log options
549 549
550 If --follow, revs are the revisions to follow from. 550 If --follow, revs are the revisions to follow from.
551 551
552 Returns (match, pats, slowpath) where 552 Returns (match, pats, slowpath) where
623 for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst): 623 for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst):
624 fcache[rev] = [c.path() for c in cs] 624 fcache[rev] = [c.path() for c in cs]
625 yield rev 625 yield rev
626 return smartset.generatorset(revgen(), iterasc=False), filematcher 626 return smartset.generatorset(revgen(), iterasc=False), filematcher
627 627
628 def _makenofollowlogfilematcher(repo, pats, opts): 628 def _makenofollowfilematcher(repo, pats, opts):
629 '''hook for extensions to override the filematcher for non-follow cases''' 629 '''hook for extensions to override the filematcher for non-follow cases'''
630 return None 630 return None
631 631
632 _opt2logrevset = { 632 _opt2logrevset = {
633 'no_merges': ('not merge()', None), 633 'no_merges': ('not merge()', None),
639 'keyword': ('keyword(%s)', '%lr'), 639 'keyword': ('keyword(%s)', '%lr'),
640 'prune': ('ancestors(%s)', 'not %lr'), 640 'prune': ('ancestors(%s)', 'not %lr'),
641 'user': ('user(%s)', '%lr'), 641 'user': ('user(%s)', '%lr'),
642 } 642 }
643 643
644 def _makelogrevset(repo, match, pats, slowpath, opts): 644 def _makerevset(repo, match, pats, slowpath, opts):
645 """Return a revset string built from log options and file patterns""" 645 """Return a revset string built from log options and file patterns"""
646 opts = dict(opts) 646 opts = dict(opts)
647 # follow or not follow? 647 # follow or not follow?
648 follow = opts.get('follow') or opts.get('follow_first') 648 follow = opts.get('follow') or opts.get('follow_first')
649 649
692 expr = '(' + ' and '.join(expr) + ')' 692 expr = '(' + ' and '.join(expr) + ')'
693 else: 693 else:
694 expr = None 694 expr = None
695 return expr 695 return expr
696 696
697 def _logrevs(repo, opts): 697 def _initialrevs(repo, opts):
698 """Return the initial set of revisions to be filtered or followed""" 698 """Return the initial set of revisions to be filtered or followed"""
699 follow = opts.get('follow') or opts.get('follow_first') 699 follow = opts.get('follow') or opts.get('follow_first')
700 if opts.get('rev'): 700 if opts.get('rev'):
701 revs = scmutil.revrange(repo, opts['rev']) 701 revs = scmutil.revrange(repo, opts['rev'])
702 elif follow and repo.dirstate.p1() == nullid: 702 elif follow and repo.dirstate.p1() == nullid:
706 else: 706 else:
707 revs = smartset.spanset(repo) 707 revs = smartset.spanset(repo)
708 revs.reverse() 708 revs.reverse()
709 return revs 709 return revs
710 710
711 def getlogrevs(repo, pats, opts): 711 def getrevs(repo, pats, opts):
712 """Return (revs, filematcher) where revs is a smartset 712 """Return (revs, filematcher) where revs is a smartset
713 713
714 filematcher is a callable taking a revision number and returning a match 714 filematcher is a callable taking a revision number and returning a match
715 objects filtering the files to be detailed when displaying the revision. 715 objects filtering the files to be detailed when displaying the revision.
716 """ 716 """
717 follow = opts.get('follow') or opts.get('follow_first') 717 follow = opts.get('follow') or opts.get('follow_first')
718 followfirst = opts.get('follow_first') 718 followfirst = opts.get('follow_first')
719 limit = loglimit(opts) 719 limit = getlimit(opts)
720 revs = _logrevs(repo, opts) 720 revs = _initialrevs(repo, opts)
721 if not revs: 721 if not revs:
722 return smartset.baseset(), None 722 return smartset.baseset(), None
723 match, pats, slowpath = _makelogmatcher(repo, revs, pats, opts) 723 match, pats, slowpath = _makematcher(repo, revs, pats, opts)
724 filematcher = None 724 filematcher = None
725 if follow: 725 if follow:
726 if slowpath or match.always(): 726 if slowpath or match.always():
727 revs = dagop.revancestors(repo, revs, followfirst=followfirst) 727 revs = dagop.revancestors(repo, revs, followfirst=followfirst)
728 else: 728 else:
729 revs, filematcher = _fileancestors(repo, revs, match, followfirst) 729 revs, filematcher = _fileancestors(repo, revs, match, followfirst)
730 revs.reverse() 730 revs.reverse()
731 if filematcher is None: 731 if filematcher is None:
732 filematcher = _makenofollowlogfilematcher(repo, pats, opts) 732 filematcher = _makenofollowfilematcher(repo, pats, opts)
733 if filematcher is None: 733 if filematcher is None:
734 def filematcher(rev): 734 def filematcher(rev):
735 return match 735 return match
736 736
737 expr = _makelogrevset(repo, match, pats, slowpath, opts) 737 expr = _makerevset(repo, match, pats, slowpath, opts)
738 if opts.get('graph') and opts.get('rev'): 738 if opts.get('graph') and opts.get('rev'):
739 # User-specified revs might be unsorted, but don't sort before 739 # User-specified revs might be unsorted, but don't sort before
740 # _makelogrevset because it might depend on the order of revs 740 # _makerevset because it might depend on the order of revs
741 if not (revs.isdescending() or revs.istopo()): 741 if not (revs.isdescending() or revs.istopo()):
742 revs.sort(reverse=True) 742 revs.sort(reverse=True)
743 if expr: 743 if expr:
744 matcher = revset.match(None, expr) 744 matcher = revset.match(None, expr)
745 revs = matcher(repo, revs) 745 revs = matcher(repo, revs)
746 if limit is not None: 746 if limit is not None:
747 revs = revs.slice(0, limit) 747 revs = revs.slice(0, limit)
748 return revs, filematcher 748 return revs, filematcher
749 749
750 def _parselinerangelogopt(repo, opts): 750 def _parselinerangeopt(repo, opts):
751 """Parse --line-range log option and return a list of tuples (filename, 751 """Parse --line-range log option and return a list of tuples (filename,
752 (fromline, toline)). 752 (fromline, toline)).
753 """ 753 """
754 linerangebyfname = [] 754 linerangebyfname = []
755 for pat in opts.get('line_range', []): 755 for pat in opts.get('line_range', []):
765 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg) 765 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
766 linerangebyfname.append( 766 linerangebyfname.append(
767 (fname, util.processlinerange(fromline, toline))) 767 (fname, util.processlinerange(fromline, toline)))
768 return linerangebyfname 768 return linerangebyfname
769 769
770 def getloglinerangerevs(repo, userrevs, opts): 770 def getlinerangerevs(repo, userrevs, opts):
771 """Return (revs, filematcher, hunksfilter). 771 """Return (revs, filematcher, hunksfilter).
772 772
773 "revs" are revisions obtained by processing "line-range" log options and 773 "revs" are revisions obtained by processing "line-range" log options and
774 walking block ancestors of each specified file/line-range. 774 walking block ancestors of each specified file/line-range.
775 775
783 """ 783 """
784 wctx = repo[None] 784 wctx = repo[None]
785 785
786 # Two-levels map of "rev -> file ctx -> [line range]". 786 # Two-levels map of "rev -> file ctx -> [line range]".
787 linerangesbyrev = {} 787 linerangesbyrev = {}
788 for fname, (fromline, toline) in _parselinerangelogopt(repo, opts): 788 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
789 if fname not in wctx: 789 if fname not in wctx:
790 raise error.Abort(_('cannot follow file not in parent ' 790 raise error.Abort(_('cannot follow file not in parent '
791 'revision: "%s"') % fname) 791 'revision: "%s"') % fname)
792 fctx = wctx.filectx(fname) 792 fctx = wctx.filectx(fname)
793 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline): 793 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
924 if op in opts and opts[op]: 924 if op in opts and opts[op]:
925 raise error.Abort(_("-G/--graph option is incompatible with --%s") 925 raise error.Abort(_("-G/--graph option is incompatible with --%s")
926 % op.replace("_", "-")) 926 % op.replace("_", "-"))
927 927
928 def graphrevs(repo, nodes, opts): 928 def graphrevs(repo, nodes, opts):
929 limit = loglimit(opts) 929 limit = getlimit(opts)
930 nodes.reverse() 930 nodes.reverse()
931 if limit is not None: 931 if limit is not None:
932 nodes = nodes[:limit] 932 nodes = nodes[:limit]
933 return graphmod.nodes(repo, nodes) 933 return graphmod.nodes(repo, nodes)