##// END OF EJS Templates
log: pack filematcher and hunksfilter into changesetdiffer object...
Yuya Nishihara -
r36024:29b83c08 default
parent child Browse files
Show More
@@ -3419,17 +3419,15 b' def log(ui, repo, *pats, **opts):'
3419 )
3419 )
3420
3420
3421 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3421 repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
3422 revs, filematcher = logcmdutil.getrevs(repo, pats, opts)
3422 revs, differ = logcmdutil.getrevs(repo, pats, opts)
3423 hunksfilter = None
3424
3423
3425 if opts.get('graph'):
3424 if opts.get('graph'):
3426 if linerange:
3425 if linerange:
3427 raise error.Abort(_('graph not supported with line range patterns'))
3426 raise error.Abort(_('graph not supported with line range patterns'))
3428 return logcmdutil.graphlog(ui, repo, revs, filematcher, opts)
3427 return logcmdutil.graphlog(ui, repo, revs, differ, opts)
3429
3428
3430 if linerange:
3429 if linerange:
3431 revs, filematcher, hunksfilter = logcmdutil.getlinerangerevs(
3430 revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
3432 repo, revs, opts)
3433
3431
3434 getrenamed = None
3432 getrenamed = None
3435 if opts.get('copies'):
3433 if opts.get('copies'):
@@ -3439,9 +3437,7 b' def log(ui, repo, *pats, **opts):'
3439 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3437 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3440
3438
3441 ui.pager('log')
3439 ui.pager('log')
3442 displayer = logcmdutil.changesetdisplayer(ui, repo, opts,
3440 displayer = logcmdutil.changesetdisplayer(ui, repo, opts, differ,
3443 makefilematcher=filematcher,
3444 makehunksfilter=hunksfilter,
3445 buffered=True)
3441 buffered=True)
3446 for rev in revs:
3442 for rev in revs:
3447 ctx = repo[rev]
3443 ctx = repo[rev]
@@ -122,6 +122,23 b' def diffordiffstat(ui, repo, diffopts, n'
122 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
122 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
123 stat=stat, fp=fp, prefix=prefix)
123 stat=stat, fp=fp, prefix=prefix)
124
124
125 class changesetdiffer(object):
126 """Generate diff of changeset with pre-configured filtering functions"""
127
128 def _makefilematcher(self, ctx):
129 return scmutil.matchall(ctx.repo())
130
131 def _makehunksfilter(self, ctx):
132 return None
133
134 def showdiff(self, ui, ctx, diffopts, stat=False):
135 repo = ctx.repo()
136 node = ctx.node()
137 prev = ctx.p1().node()
138 diffordiffstat(ui, repo, diffopts, prev, node,
139 match=self._makefilematcher(ctx), stat=stat,
140 hunksfilterfn=self._makehunksfilter(ctx))
141
125 def changesetlabels(ctx):
142 def changesetlabels(ctx):
126 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()]
143 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()]
127 if ctx.obsolete():
144 if ctx.obsolete():
@@ -135,13 +152,11 b' def changesetlabels(ctx):'
135 class changesetprinter(object):
152 class changesetprinter(object):
136 '''show changeset information when templating not requested.'''
153 '''show changeset information when templating not requested.'''
137
154
138 def __init__(self, ui, repo, makefilematcher=None, makehunksfilter=None,
155 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
139 diffopts=None, buffered=False):
140 self.ui = ui
156 self.ui = ui
141 self.repo = repo
157 self.repo = repo
142 self.buffered = buffered
158 self.buffered = buffered
143 self._makefilematcher = makefilematcher or (lambda ctx: None)
159 self._differ = differ or changesetdiffer()
144 self._makehunksfilter = makehunksfilter or (lambda ctx: None)
145 self.diffopts = diffopts or {}
160 self.diffopts = diffopts or {}
146 self.header = {}
161 self.header = {}
147 self.hunk = {}
162 self.hunk = {}
@@ -280,35 +295,23 b' class changesetprinter(object):'
280 '''
295 '''
281
296
282 def _showpatch(self, ctx):
297 def _showpatch(self, ctx):
283 matchfn = self._makefilematcher(ctx)
284 hunksfilterfn = self._makehunksfilter(ctx)
285 if not matchfn:
286 return
287 stat = self.diffopts.get('stat')
298 stat = self.diffopts.get('stat')
288 diff = self.diffopts.get('patch')
299 diff = self.diffopts.get('patch')
289 diffopts = patch.diffallopts(self.ui, self.diffopts)
300 diffopts = patch.diffallopts(self.ui, self.diffopts)
290 node = ctx.node()
291 prev = ctx.p1().node()
292 if stat:
301 if stat:
293 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
302 self._differ.showdiff(self.ui, ctx, diffopts, stat=True)
294 match=matchfn, stat=True,
295 hunksfilterfn=hunksfilterfn)
296 if stat and diff:
303 if stat and diff:
297 self.ui.write("\n")
304 self.ui.write("\n")
298 if diff:
305 if diff:
299 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
306 self._differ.showdiff(self.ui, ctx, diffopts, stat=False)
300 match=matchfn, stat=False,
301 hunksfilterfn=hunksfilterfn)
302 if stat or diff:
307 if stat or diff:
303 self.ui.write("\n")
308 self.ui.write("\n")
304
309
305 class jsonchangeset(changesetprinter):
310 class jsonchangeset(changesetprinter):
306 '''format changeset information.'''
311 '''format changeset information.'''
307
312
308 def __init__(self, ui, repo, makefilematcher=None, makehunksfilter=None,
313 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
309 diffopts=None, buffered=False):
314 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
310 changesetprinter.__init__(self, ui, repo, makefilematcher,
311 makehunksfilter, diffopts, buffered)
312 self.cache = {}
315 self.cache = {}
313 self._first = True
316 self._first = True
314
317
@@ -383,21 +386,17 b' class jsonchangeset(changesetprinter):'
383 ", ".join('"%s": "%s"' % (j(k), j(v))
386 ", ".join('"%s": "%s"' % (j(k), j(v))
384 for k, v in copies))
387 for k, v in copies))
385
388
386 matchfn = self._makefilematcher(ctx)
387 stat = self.diffopts.get('stat')
389 stat = self.diffopts.get('stat')
388 diff = self.diffopts.get('patch')
390 diff = self.diffopts.get('patch')
389 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True)
391 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True)
390 node, prev = ctx.node(), ctx.p1().node()
392 if stat:
391 if matchfn and stat:
392 self.ui.pushbuffer()
393 self.ui.pushbuffer()
393 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
394 self._differ.showdiff(self.ui, ctx, diffopts, stat=True)
394 match=matchfn, stat=True)
395 self.ui.write((',\n "diffstat": "%s"')
395 self.ui.write((',\n "diffstat": "%s"')
396 % j(self.ui.popbuffer()))
396 % j(self.ui.popbuffer()))
397 if matchfn and diff:
397 if diff:
398 self.ui.pushbuffer()
398 self.ui.pushbuffer()
399 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
399 self._differ.showdiff(self.ui, ctx, diffopts, stat=False)
400 match=matchfn, stat=False)
401 self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer()))
400 self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer()))
402
401
403 self.ui.write("\n }")
402 self.ui.write("\n }")
@@ -413,10 +412,9 b' class changesettemplater(changesetprinte'
413
412
414 # Arguments before "buffered" used to be positional. Consider not
413 # Arguments before "buffered" used to be positional. Consider not
415 # adding/removing arguments before "buffered" to not break callers.
414 # adding/removing arguments before "buffered" to not break callers.
416 def __init__(self, ui, repo, tmplspec, makefilematcher=None,
415 def __init__(self, ui, repo, tmplspec, differ=None, diffopts=None,
417 makehunksfilter=None, diffopts=None, buffered=False):
416 buffered=False):
418 changesetprinter.__init__(self, ui, repo, makefilematcher,
417 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
419 makehunksfilter, diffopts, buffered)
420 tres = formatter.templateresources(ui, repo)
418 tres = formatter.templateresources(ui, repo)
421 self.t = formatter.loadtemplater(ui, tmplspec,
419 self.t = formatter.loadtemplater(ui, tmplspec,
422 defaults=templatekw.keywords,
420 defaults=templatekw.keywords,
@@ -533,8 +531,7 b' def maketemplater(ui, repo, tmpl, buffer'
533 spec = templatespec(tmpl, None)
531 spec = templatespec(tmpl, None)
534 return changesettemplater(ui, repo, spec, buffered=buffered)
532 return changesettemplater(ui, repo, spec, buffered=buffered)
535
533
536 def changesetdisplayer(ui, repo, opts, makefilematcher=None,
534 def changesetdisplayer(ui, repo, opts, differ=None, buffered=False):
537 makehunksfilter=None, buffered=False):
538 """show one changeset using template or regular display.
535 """show one changeset using template or regular display.
539
536
540 Display format will be the first non-empty hit of:
537 Display format will be the first non-empty hit of:
@@ -545,12 +542,7 b' def changesetdisplayer(ui, repo, opts, m'
545 If all of these values are either the unset or the empty string,
542 If all of these values are either the unset or the empty string,
546 regular display via changesetprinter() is done.
543 regular display via changesetprinter() is done.
547 """
544 """
548 # options
545 postargs = (differ, opts, buffered)
549 if not makefilematcher and (opts.get('patch') or opts.get('stat')):
550 def makefilematcher(ctx):
551 return scmutil.matchall(repo)
552
553 postargs = (makefilematcher, makehunksfilter, opts, buffered)
554 if opts.get('template') == 'json':
546 if opts.get('template') == 'json':
555 return jsonchangeset(ui, repo, *postargs)
547 return jsonchangeset(ui, repo, *postargs)
556
548
@@ -726,10 +718,9 b' def _initialrevs(repo, opts):'
726 return revs
718 return revs
727
719
728 def getrevs(repo, pats, opts):
720 def getrevs(repo, pats, opts):
729 """Return (revs, filematcher) where revs is a smartset
721 """Return (revs, differ) where revs is a smartset
730
722
731 filematcher is a callable taking a changectx and returning a match
723 differ is a changesetdiffer with pre-configured file matcher.
732 objects filtering the files to be detailed when displaying the revision.
733 """
724 """
734 follow = opts.get('follow') or opts.get('follow_first')
725 follow = opts.get('follow') or opts.get('follow_first')
735 followfirst = opts.get('follow_first')
726 followfirst = opts.get('follow_first')
@@ -762,7 +753,10 b' def getrevs(repo, pats, opts):'
762 revs = matcher(repo, revs)
753 revs = matcher(repo, revs)
763 if limit is not None:
754 if limit is not None:
764 revs = revs.slice(0, limit)
755 revs = revs.slice(0, limit)
765 return revs, filematcher
756
757 differ = changesetdiffer()
758 differ._makefilematcher = filematcher
759 return revs, differ
766
760
767 def _parselinerangeopt(repo, opts):
761 def _parselinerangeopt(repo, opts):
768 """Parse --line-range log option and return a list of tuples (filename,
762 """Parse --line-range log option and return a list of tuples (filename,
@@ -785,16 +779,13 b' def _parselinerangeopt(repo, opts):'
785 return linerangebyfname
779 return linerangebyfname
786
780
787 def getlinerangerevs(repo, userrevs, opts):
781 def getlinerangerevs(repo, userrevs, opts):
788 """Return (revs, filematcher, hunksfilter).
782 """Return (revs, differ).
789
783
790 "revs" are revisions obtained by processing "line-range" log options and
784 "revs" are revisions obtained by processing "line-range" log options and
791 walking block ancestors of each specified file/line-range.
785 walking block ancestors of each specified file/line-range.
792
786
793 "filematcher(ctx) -> match" is a factory function returning a match object
787 "differ" is a changesetdiffer with pre-configured file matcher and hunks
794 for a given revision for file patterns specified in --line-range option.
788 filter.
795
796 "hunksfilter(ctx) -> filterfn(fctx, hunks)" is a factory function
797 returning a hunks filtering function.
798 """
789 """
799 wctx = repo[None]
790 wctx = repo[None]
800
791
@@ -843,7 +834,10 b' def getlinerangerevs(repo, userrevs, opt'
843
834
844 revs = sorted(linerangesbyrev, reverse=True)
835 revs = sorted(linerangesbyrev, reverse=True)
845
836
846 return revs, filematcher, hunksfilter
837 differ = changesetdiffer()
838 differ._makefilematcher = filematcher
839 differ._makehunksfilter = hunksfilter
840 return revs, differ
847
841
848 def _graphnodeformatter(ui, displayer):
842 def _graphnodeformatter(ui, displayer):
849 spec = ui.config('ui', 'graphnodetemplate')
843 spec = ui.config('ui', 'graphnodetemplate')
@@ -910,7 +904,7 b' def displaygraph(ui, repo, dag, displaye'
910 lines = []
904 lines = []
911 displayer.close()
905 displayer.close()
912
906
913 def graphlog(ui, repo, revs, filematcher, opts):
907 def graphlog(ui, repo, revs, differ, opts):
914 # Parameters are identical to log command ones
908 # Parameters are identical to log command ones
915 revdag = graphmod.dagwalker(repo, revs)
909 revdag = graphmod.dagwalker(repo, revs)
916
910
@@ -922,8 +916,7 b' def graphlog(ui, repo, revs, filematcher'
922 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
916 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
923
917
924 ui.pager('log')
918 ui.pager('log')
925 displayer = changesetdisplayer(ui, repo, opts, makefilematcher=filematcher,
919 displayer = changesetdisplayer(ui, repo, opts, differ, buffered=True)
926 buffered=True)
927 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
920 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
928
921
929 def checkunsupportedgraphflags(pats, opts):
922 def checkunsupportedgraphflags(pats, opts):
General Comments 0
You need to be logged in to leave comments. Login now