##// END OF EJS Templates
log: introduce struct that carries log traversal options...
Yuya Nishihara -
r46139:c1d0f83d default
parent child Browse files
Show More
@@ -137,9 +137,9 b' def _setuplog(ui):'
137 137 )
138 138 )
139 139
140 def _initialrevs(orig, repo, opts):
141 revs = orig(repo, opts)
142 if opts.get(b'sparse'):
140 def _initialrevs(orig, repo, wopts):
141 revs = orig(repo, wopts)
142 if wopts.opts.get(b'sparse'):
143 143 sparsematch = sparse.matcher(repo)
144 144
145 145 def ctxmatch(rev):
@@ -4734,7 +4734,9 b' def log(ui, repo, *pats, **opts):'
4734 4734 )
4735 4735
4736 4736 repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
4737 revs, differ = logcmdutil.getrevs(repo, pats, opts)
4737 revs, differ = logcmdutil.getrevs(
4738 repo, logcmdutil.parseopts(ui, pats, opts)
4739 )
4738 4740 if linerange:
4739 4741 # TODO: should follow file history from logcmdutil._initialrevs(),
4740 4742 # then filter the result by logcmdutil._makerevset() and --limit
@@ -18,6 +18,8 b' from .node import ('
18 18 wdirrev,
19 19 )
20 20
21 from .thirdparty import attr
22
21 23 from . import (
22 24 dagop,
23 25 error,
@@ -45,11 +47,13 b' from .utils import ('
45 47 if pycompat.TYPE_CHECKING:
46 48 from typing import (
47 49 Any,
50 Dict,
51 List,
48 52 Optional,
49 53 Tuple,
50 54 )
51 55
52 for t in (Any, Optional, Tuple):
56 for t in (Any, Dict, List, Optional, Tuple):
53 57 assert t
54 58
55 59
@@ -672,7 +676,27 b' def changesetdisplayer(ui, repo, opts, d'
672 676 return changesettemplater(ui, repo, spec, *postargs)
673 677
674 678
675 def _makematcher(repo, revs, pats, opts):
679 @attr.s
680 class walkopts(object):
681 """Options to configure a set of revisions and file matcher factory
682 to scan revision/file history
683 """
684
685 # raw command-line parameters, which a matcher will be built from
686 pats = attr.ib() # type: List[bytes]
687 opts = attr.ib() # type: Dict[bytes, Any]
688
689
690 def parseopts(ui, pats, opts):
691 # type: (Any, List[bytes], Dict[bytes, Any]) -> walkopts
692 """Parse log command options into walkopts
693
694 The returned walkopts will be passed in to getrevs().
695 """
696 return walkopts(pats=pats, opts=opts)
697
698
699 def _makematcher(repo, revs, wopts):
676 700 """Build matcher and expanded patterns from log options
677 701
678 702 If --follow, revs are the revisions to follow from.
@@ -687,11 +711,13 b' def _makematcher(repo, revs, pats, opts)'
687 711 # scmutil.match(). The difference is input pats are globbed on
688 712 # platforms without shell expansion (windows).
689 713 wctx = repo[None]
690 match, pats = scmutil.matchandpats(wctx, pats, opts)
691 slowpath = match.anypats() or (not match.always() and opts.get(b'removed'))
714 match, pats = scmutil.matchandpats(wctx, wopts.pats, wopts.opts)
715 slowpath = match.anypats() or (
716 not match.always() and wopts.opts.get(b'removed')
717 )
692 718 if not slowpath:
693 follow = opts.get(b'follow') or opts.get(b'follow_first')
694 if follow and opts.get(b'rev'):
719 follow = wopts.opts.get(b'follow') or wopts.opts.get(b'follow_first')
720 if follow and wopts.opts.get(b'rev'):
695 721 # There may be the case that a path doesn't exist in some (but
696 722 # not all) of the specified start revisions, but let's consider
697 723 # the path is valid. Missing files will be warned by the matcher.
@@ -800,9 +826,9 b' def _makenofollowfilematcher(repo, pats,'
800 826 }
801 827
802 828
803 def _makerevset(repo, pats, slowpath, opts):
829 def _makerevset(repo, wopts, slowpath):
804 830 """Return a revset string built from log options and file patterns"""
805 opts = dict(opts)
831 opts = dict(wopts.opts)
806 832 # follow or not follow?
807 833 follow = opts.get(b'follow') or opts.get(b'follow_first')
808 834
@@ -821,7 +847,7 b' def _makerevset(repo, pats, slowpath, op'
821 847 # not. Besides, filesets are evaluated against the working
822 848 # directory.
823 849 matchargs = [b'r:', b'd:relpath']
824 for p in pats:
850 for p in wopts.pats:
825 851 matchargs.append(b'p:' + p)
826 852 for p in opts.get(b'include', []):
827 853 matchargs.append(b'i:' + p)
@@ -829,7 +855,7 b' def _makerevset(repo, pats, slowpath, op'
829 855 matchargs.append(b'x:' + p)
830 856 opts[b'_matchfiles'] = matchargs
831 857 elif not follow:
832 opts[b'_patslog'] = list(pats)
858 opts[b'_patslog'] = list(wopts.pats)
833 859
834 860 expr = []
835 861 for op, val in sorted(pycompat.iteritems(opts)):
@@ -854,11 +880,11 b' def _makerevset(repo, pats, slowpath, op'
854 880 return expr
855 881
856 882
857 def _initialrevs(repo, opts):
883 def _initialrevs(repo, wopts):
858 884 """Return the initial set of revisions to be filtered or followed"""
859 follow = opts.get(b'follow') or opts.get(b'follow_first')
860 if opts.get(b'rev'):
861 revs = scmutil.revrange(repo, opts[b'rev'])
885 follow = wopts.opts.get(b'follow') or wopts.opts.get(b'follow_first')
886 if wopts.opts.get(b'rev'):
887 revs = scmutil.revrange(repo, wopts.opts[b'rev'])
862 888 elif follow and repo.dirstate.p1() == nullid:
863 889 revs = smartset.baseset()
864 890 elif follow:
@@ -869,19 +895,21 b' def _initialrevs(repo, opts):'
869 895 return revs
870 896
871 897
872 def getrevs(repo, pats, opts):
873 # type: (Any, Any, Any) -> Tuple[smartset.abstractsmartset, Optional[changesetdiffer]]
898 def getrevs(repo, wopts):
899 # type: (Any, walkopts) -> Tuple[smartset.abstractsmartset, Optional[changesetdiffer]]
874 900 """Return (revs, differ) where revs is a smartset
875 901
876 902 differ is a changesetdiffer with pre-configured file matcher.
877 903 """
878 follow = opts.get(b'follow') or opts.get(b'follow_first')
879 followfirst = opts.get(b'follow_first')
880 limit = getlimit(opts)
881 revs = _initialrevs(repo, opts)
904 follow = wopts.opts.get(b'follow') or wopts.opts.get(b'follow_first')
905 followfirst = wopts.opts.get(b'follow_first')
906 limit = getlimit(wopts.opts)
907 revs = _initialrevs(repo, wopts)
882 908 if not revs:
883 909 return smartset.baseset(), None
884 match, pats, slowpath = _makematcher(repo, revs, pats, opts)
910 match, pats, slowpath = _makematcher(repo, revs, wopts)
911 wopts = attr.evolve(wopts, pats=pats)
912
885 913 filematcher = None
886 914 if follow:
887 915 if slowpath or match.always():
@@ -890,14 +918,14 b' def getrevs(repo, pats, opts):'
890 918 revs, filematcher = _fileancestors(repo, revs, match, followfirst)
891 919 revs.reverse()
892 920 if filematcher is None:
893 filematcher = _makenofollowfilematcher(repo, pats, opts)
921 filematcher = _makenofollowfilematcher(repo, wopts.pats, wopts.opts)
894 922 if filematcher is None:
895 923
896 924 def filematcher(ctx):
897 925 return match
898 926
899 expr = _makerevset(repo, pats, slowpath, opts)
900 if opts.get(b'graph'):
927 expr = _makerevset(repo, wopts, slowpath)
928 if wopts.opts.get(b'graph'):
901 929 if repo.ui.configbool(b'experimental', b'log.topo'):
902 930 if not revs.istopo():
903 931 revs = dagop.toposort(revs, repo.changelog.parentrevs)
@@ -1,4 +1,5 b''
1 1 from __future__ import absolute_import
2 from mercurial.thirdparty import attr
2 3 from mercurial import (
3 4 cmdutil,
4 5 commands,
@@ -11,26 +12,27 b' from mercurial import ('
11 12 from mercurial.utils import stringutil
12 13
13 14
14 def logrevset(repo, pats, opts):
15 revs = logcmdutil._initialrevs(repo, opts)
15 def logrevset(repo, wopts):
16 revs = logcmdutil._initialrevs(repo, wopts)
16 17 if not revs:
17 18 return None
18 match, pats, slowpath = logcmdutil._makematcher(repo, revs, pats, opts)
19 return logcmdutil._makerevset(repo, pats, slowpath, opts)
19 match, pats, slowpath = logcmdutil._makematcher(repo, revs, wopts)
20 wopts = attr.evolve(wopts, pats=pats)
21 return logcmdutil._makerevset(repo, wopts, slowpath)
20 22
21 23
22 24 def uisetup(ui):
23 def printrevset(orig, repo, pats, opts):
24 revs, filematcher = orig(repo, pats, opts)
25 if opts.get(b'print_revset'):
26 expr = logrevset(repo, pats, opts)
25 def printrevset(orig, repo, wopts):
26 revs, filematcher = orig(repo, wopts)
27 if wopts.opts.get(b'print_revset'):
28 expr = logrevset(repo, wopts)
27 29 if expr:
28 30 tree = revsetlang.parse(expr)
29 31 tree = revsetlang.analyze(tree)
30 32 else:
31 33 tree = []
32 34 ui = repo.ui
33 ui.write(b'%s\n' % stringutil.pprint(opts.get(b'rev', [])))
35 ui.write(b'%s\n' % stringutil.pprint(wopts.opts.get(b'rev', [])))
34 36 ui.write(revsetlang.prettyformat(tree) + b'\n')
35 37 ui.write(stringutil.prettyrepr(revs) + b'\n')
36 38 revs = smartset.baseset() # display no revisions
General Comments 0
You need to be logged in to leave comments. Login now