107 tempnode2 = None |
107 tempnode2 = None |
108 submatch = matchmod.subdirmatcher(subpath, match) |
108 submatch = matchmod.subdirmatcher(subpath, match) |
109 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes, |
109 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes, |
110 stat=stat, fp=fp, prefix=prefix) |
110 stat=stat, fp=fp, prefix=prefix) |
111 |
111 |
112 def _changesetlabels(ctx): |
112 def changesetlabels(ctx): |
113 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()] |
113 labels = ['log.changeset', 'changeset.%s' % ctx.phasestr()] |
114 if ctx.obsolete(): |
114 if ctx.obsolete(): |
115 labels.append('changeset.obsolete') |
115 labels.append('changeset.obsolete') |
116 if ctx.isunstable(): |
116 if ctx.isunstable(): |
117 labels.append('changeset.unstable') |
117 labels.append('changeset.unstable') |
118 for instability in ctx.instabilities(): |
118 for instability in ctx.instabilities(): |
119 labels.append('instability.%s' % instability) |
119 labels.append('instability.%s' % instability) |
120 return ' '.join(labels) |
120 return ' '.join(labels) |
121 |
121 |
122 class changeset_printer(object): |
122 class changesetprinter(object): |
123 '''show changeset information when templating not requested.''' |
123 '''show changeset information when templating not requested.''' |
124 |
124 |
125 def __init__(self, ui, repo, matchfn, diffopts, buffered): |
125 def __init__(self, ui, repo, matchfn, diffopts, buffered): |
126 self.ui = ui |
126 self.ui = ui |
127 self.repo = repo |
127 self.repo = repo |
170 label='log.node') |
170 label='log.node') |
171 return |
171 return |
172 |
172 |
173 columns = self._columns |
173 columns = self._columns |
174 self.ui.write(columns['changeset'] % scmutil.formatchangeid(ctx), |
174 self.ui.write(columns['changeset'] % scmutil.formatchangeid(ctx), |
175 label=_changesetlabels(ctx)) |
175 label=changesetlabels(ctx)) |
176 |
176 |
177 # branches are shown first before any other names due to backwards |
177 # branches are shown first before any other names due to backwards |
178 # compatibility |
178 # compatibility |
179 branch = ctx.branch() |
179 branch = ctx.branch() |
180 # don't show the default branch name |
180 # don't show the default branch name |
285 match=matchfn, stat=False, |
285 match=matchfn, stat=False, |
286 hunksfilterfn=hunksfilterfn) |
286 hunksfilterfn=hunksfilterfn) |
287 if stat or diff: |
287 if stat or diff: |
288 self.ui.write("\n") |
288 self.ui.write("\n") |
289 |
289 |
290 class jsonchangeset(changeset_printer): |
290 class jsonchangeset(changesetprinter): |
291 '''format changeset information.''' |
291 '''format changeset information.''' |
292 |
292 |
293 def __init__(self, ui, repo, matchfn, diffopts, buffered): |
293 def __init__(self, ui, repo, matchfn, diffopts, buffered): |
294 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered) |
294 changesetprinter.__init__(self, ui, repo, matchfn, diffopts, buffered) |
295 self.cache = {} |
295 self.cache = {} |
296 self._first = True |
296 self._first = True |
297 |
297 |
298 def close(self): |
298 def close(self): |
299 if not self._first: |
299 if not self._first: |
384 match=matchfn, stat=False) |
384 match=matchfn, stat=False) |
385 self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer())) |
385 self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer())) |
386 |
386 |
387 self.ui.write("\n }") |
387 self.ui.write("\n }") |
388 |
388 |
389 class changeset_templater(changeset_printer): |
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 changeset_templater for common cases. See functions such as: |
393 changesettemplater for common cases. See functions such as: |
394 makelogtemplater, show_changeset, buildcommittemplate, or other |
394 makelogtemplater, 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. |
400 def __init__(self, ui, repo, tmplspec, matchfn=None, diffopts=None, |
400 def __init__(self, ui, repo, tmplspec, matchfn=None, diffopts=None, |
401 buffered=False): |
401 buffered=False): |
402 diffopts = diffopts or {} |
402 diffopts = diffopts or {} |
403 |
403 |
404 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered) |
404 changesetprinter.__init__(self, ui, repo, matchfn, diffopts, buffered) |
405 tres = formatter.templateresources(ui, repo) |
405 tres = formatter.templateresources(ui, repo) |
406 self.t = formatter.loadtemplater(ui, tmplspec, |
406 self.t = formatter.loadtemplater(ui, tmplspec, |
407 defaults=templatekw.keywords, |
407 defaults=templatekw.keywords, |
408 resources=tres, |
408 resources=tres, |
409 cache=templatekw.defaulttempl) |
409 cache=templatekw.defaulttempl) |
440 def close(self): |
440 def close(self): |
441 if self._parts['docfooter']: |
441 if self._parts['docfooter']: |
442 if not self.footer: |
442 if not self.footer: |
443 self.footer = "" |
443 self.footer = "" |
444 self.footer += templater.stringify(self.t(self._parts['docfooter'])) |
444 self.footer += templater.stringify(self.t(self._parts['docfooter'])) |
445 return super(changeset_templater, self).close() |
445 return super(changesettemplater, self).close() |
446 |
446 |
447 def _show(self, ctx, copies, matchfn, hunksfilterfn, props): |
447 def _show(self, ctx, copies, matchfn, hunksfilterfn, props): |
448 '''show a single changeset or file revision''' |
448 '''show a single changeset or file revision''' |
449 props = props.copy() |
449 props = props.copy() |
450 props['ctx'] = ctx |
450 props['ctx'] = ctx |
511 return logtemplatespec(None, None) |
511 return logtemplatespec(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 makelogtemplater(ui, repo, tmpl, buffered=False): |
516 """Create a changeset_templater 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 = logtemplatespec(tmpl, None) |
519 return changeset_templater(ui, repo, spec, buffered=buffered) |
519 return changesettemplater(ui, repo, spec, buffered=buffered) |
520 |
520 |
521 def show_changeset(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 |
524 Display format will be the first non-empty hit of: |
524 Display format will be the first non-empty hit of: |
525 1. option 'template' |
525 1. option 'template' |
526 2. option 'style' |
526 2. option 'style' |
527 3. [ui] setting 'logtemplate' |
527 3. [ui] setting 'logtemplate' |
528 4. [ui] setting 'style' |
528 4. [ui] setting 'style' |
529 If all of these values are either the unset or the empty string, |
529 If all of these values are either the unset or the empty string, |
530 regular display via changeset_printer() is done. |
530 regular display via changesetprinter() is done. |
531 """ |
531 """ |
532 # options |
532 # options |
533 match = None |
533 match = None |
534 if opts.get('patch') or opts.get('stat'): |
534 if opts.get('patch') or opts.get('stat'): |
535 match = scmutil.matchall(repo) |
535 match = scmutil.matchall(repo) |
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 = _lookuplogtemplate(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 changeset_printer(ui, repo, match, opts, buffered) |
543 return changesetprinter(ui, repo, match, opts, buffered) |
544 |
544 |
545 return changeset_templater(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 _makelogmatcher(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. |
839 if not spec: |
839 if not spec: |
840 return templatekw.showgraphnode # fast path for "{graphnode}" |
840 return templatekw.showgraphnode # fast path for "{graphnode}" |
841 |
841 |
842 spec = templater.unquotestring(spec) |
842 spec = templater.unquotestring(spec) |
843 tres = formatter.templateresources(ui) |
843 tres = formatter.templateresources(ui) |
844 if isinstance(displayer, changeset_templater): |
844 if isinstance(displayer, changesettemplater): |
845 tres['cache'] = displayer.cache # reuse cache of slow templates |
845 tres['cache'] = displayer.cache # reuse cache of slow templates |
846 templ = formatter.maketemplater(ui, spec, defaults=templatekw.keywords, |
846 templ = formatter.maketemplater(ui, spec, defaults=templatekw.keywords, |
847 resources=tres) |
847 resources=tres) |
848 def formatnode(repo, ctx): |
848 def formatnode(repo, ctx): |
849 props = {'ctx': ctx, 'repo': repo, 'revcache': {}} |
849 props = {'ctx': ctx, 'repo': repo, 'revcache': {}} |
913 if opts.get('rev'): |
913 if opts.get('rev'): |
914 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1 |
914 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1 |
915 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev) |
915 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev) |
916 |
916 |
917 ui.pager('log') |
917 ui.pager('log') |
918 displayer = show_changeset(ui, repo, opts, buffered=True) |
918 displayer = changesetdisplayer(ui, repo, opts, buffered=True) |
919 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed, |
919 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed, |
920 filematcher) |
920 filematcher) |
921 |
921 |
922 def checkunsupportedgraphflags(pats, opts): |
922 def checkunsupportedgraphflags(pats, opts): |
923 for op in ["newest_first"]: |
923 for op in ["newest_first"]: |