Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/logcmdutil.py @ 37772:814151cd8c4a
logcmdutil: rewrite jsonchangeset printer to be backed by jsonformatter
This is a bit slower than the original implementation, but I don't think
that would actually matter. It's still faster than full templating.
$ hg log -Tjson -r0:5000 --time > /dev/null
(orig) time: real 1.550 secs (user 1.500+0.000 sys 0.040+0.000)
(new) time: real 1.810 secs (user 1.740+0.000 sys 0.070+0.000)
cf.
$ hg log -Tdefault -r0:5000 --time > /dev/null
time: real 4.980 secs (user 4.850+0.000 sys 0.130+0.000)
$ hg log -r0:5000 --time > /dev/null
time: real 2.340 secs (user 2.220+0.000 sys 0.100+0.000)
$ hg log -r0:5000 -q --time > /dev/null
time: real 0.750 secs (user 0.670+0.000 sys 0.070+0.000)
The test output changes because keys are sorted alphabetically.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Fri, 13 Apr 2018 22:47:14 +0900 |
parents | 8c48a3c088a7 |
children | 0f084741cd66 |
comparison
equal
deleted
inserted
replaced
37771:8c48a3c088a7 | 37772:814151cd8c4a |
---|---|
10 import itertools | 10 import itertools |
11 import os | 11 import os |
12 | 12 |
13 from .i18n import _ | 13 from .i18n import _ |
14 from .node import ( | 14 from .node import ( |
15 hex, | |
16 nullid, | 15 nullid, |
17 ) | 16 ) |
18 | 17 |
19 from . import ( | 18 from . import ( |
20 dagop, | 19 dagop, |
21 encoding, | |
22 error, | 20 error, |
23 formatter, | 21 formatter, |
24 graphmod, | 22 graphmod, |
25 match as matchmod, | 23 match as matchmod, |
26 mdiff, | 24 mdiff, |
315 class jsonchangeset(changesetprinter): | 313 class jsonchangeset(changesetprinter): |
316 '''format changeset information.''' | 314 '''format changeset information.''' |
317 | 315 |
318 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False): | 316 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False): |
319 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered) | 317 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered) |
320 self._first = True | 318 self._fm = formatter.jsonformatter(ui, ui, 'log', {}) |
321 | 319 |
322 def close(self): | 320 def close(self): |
323 if not self._first: | 321 self._fm.end() |
324 self.ui.write("\n]\n") | |
325 else: | |
326 self.ui.write("[]\n") | |
327 | 322 |
328 def _show(self, ctx, copies, props): | 323 def _show(self, ctx, copies, props): |
329 '''show a single changeset or file revision''' | 324 '''show a single changeset or file revision''' |
325 fm = self._fm | |
326 fm.startitem() | |
327 | |
328 # TODO: maybe this should be wdirrev/wdirnode? | |
330 rev = ctx.rev() | 329 rev = ctx.rev() |
331 if rev is None: | 330 if rev is None: |
332 jrev = jnode = 'null' | 331 hexnode = None |
333 else: | 332 else: |
334 jrev = '%d' % rev | 333 hexnode = fm.hexfunc(ctx.node()) |
335 jnode = '"%s"' % hex(ctx.node()) | 334 fm.data(rev=rev, |
336 j = encoding.jsonescape | 335 node=hexnode) |
337 | |
338 if self._first: | |
339 self.ui.write("[\n {") | |
340 self._first = False | |
341 else: | |
342 self.ui.write(",\n {") | |
343 | 336 |
344 if self.ui.quiet: | 337 if self.ui.quiet: |
345 self.ui.write(('\n "rev": %s') % jrev) | |
346 self.ui.write((',\n "node": %s') % jnode) | |
347 self.ui.write('\n }') | |
348 return | 338 return |
349 | 339 |
350 self.ui.write(('\n "rev": %s') % jrev) | 340 fm.data(branch=ctx.branch(), |
351 self.ui.write((',\n "node": %s') % jnode) | 341 phase=ctx.phasestr(), |
352 self.ui.write((',\n "branch": "%s"') % j(ctx.branch())) | 342 user=ctx.user(), |
353 self.ui.write((',\n "phase": "%s"') % ctx.phasestr()) | 343 date=fm.formatdate(ctx.date()), |
354 self.ui.write((',\n "user": "%s"') % j(ctx.user())) | 344 desc=ctx.description(), |
355 self.ui.write((',\n "date": [%d, %d]') % ctx.date()) | 345 bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'), |
356 self.ui.write((',\n "desc": "%s"') % j(ctx.description())) | 346 tags=fm.formatlist(ctx.tags(), name='tag'), |
357 | 347 parents=fm.formatlist([fm.hexfunc(c.node()) |
358 self.ui.write((',\n "bookmarks": [%s]') % | 348 for c in ctx.parents()], name='node')) |
359 ", ".join('"%s"' % j(b) for b in ctx.bookmarks())) | |
360 self.ui.write((',\n "tags": [%s]') % | |
361 ", ".join('"%s"' % j(t) for t in ctx.tags())) | |
362 self.ui.write((',\n "parents": [%s]') % | |
363 ", ".join('"%s"' % c.hex() for c in ctx.parents())) | |
364 | 349 |
365 if self.ui.debugflag: | 350 if self.ui.debugflag: |
366 if rev is None: | 351 if rev is None: |
367 jmanifestnode = 'null' | 352 hexnode = None |
368 else: | 353 else: |
369 jmanifestnode = '"%s"' % hex(ctx.manifestnode()) | 354 hexnode = fm.hexfunc(ctx.manifestnode()) |
370 self.ui.write((',\n "manifest": %s') % jmanifestnode) | 355 fm.data(manifest=hexnode, |
371 | 356 extra=fm.formatdict(ctx.extra())) |
372 self.ui.write((',\n "extra": {%s}') % | |
373 ", ".join('"%s": "%s"' % (j(k), j(v)) | |
374 for k, v in ctx.extra().items())) | |
375 | 357 |
376 files = ctx.p1().status(ctx) | 358 files = ctx.p1().status(ctx) |
377 self.ui.write((',\n "modified": [%s]') % | 359 fm.data(modified=fm.formatlist(files[0], name='file'), |
378 ", ".join('"%s"' % j(f) for f in files[0])) | 360 added=fm.formatlist(files[1], name='file'), |
379 self.ui.write((',\n "added": [%s]') % | 361 removed=fm.formatlist(files[2], name='file')) |
380 ", ".join('"%s"' % j(f) for f in files[1])) | |
381 self.ui.write((',\n "removed": [%s]') % | |
382 ", ".join('"%s"' % j(f) for f in files[2])) | |
383 | 362 |
384 elif self.ui.verbose: | 363 elif self.ui.verbose: |
385 self.ui.write((',\n "files": [%s]') % | 364 fm.data(files=fm.formatlist(ctx.files(), name='file')) |
386 ", ".join('"%s"' % j(f) for f in ctx.files())) | |
387 | |
388 if copies: | 365 if copies: |
389 self.ui.write((',\n "copies": {%s}') % | 366 fm.data(copies=fm.formatdict(copies, |
390 ", ".join('"%s": "%s"' % (j(k), j(v)) | 367 key='name', value='source')) |
391 for k, v in copies)) | |
392 | 368 |
393 stat = self.diffopts.get('stat') | 369 stat = self.diffopts.get('stat') |
394 diff = self.diffopts.get('patch') | 370 diff = self.diffopts.get('patch') |
395 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True) | 371 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True) |
396 if stat: | 372 if stat: |
397 self.ui.pushbuffer() | 373 self.ui.pushbuffer() |
398 self._differ.showdiff(self.ui, ctx, diffopts, stat=True) | 374 self._differ.showdiff(self.ui, ctx, diffopts, stat=True) |
399 self.ui.write((',\n "diffstat": "%s"') | 375 fm.data(diffstat=self.ui.popbuffer()) |
400 % j(self.ui.popbuffer())) | |
401 if diff: | 376 if diff: |
402 self.ui.pushbuffer() | 377 self.ui.pushbuffer() |
403 self._differ.showdiff(self.ui, ctx, diffopts, stat=False) | 378 self._differ.showdiff(self.ui, ctx, diffopts, stat=False) |
404 self.ui.write((',\n "diff": "%s"') % j(self.ui.popbuffer())) | 379 fm.data(diff=self.ui.popbuffer()) |
405 | |
406 self.ui.write("\n }") | |
407 | 380 |
408 class changesettemplater(changesetprinter): | 381 class changesettemplater(changesetprinter): |
409 '''format changeset information. | 382 '''format changeset information. |
410 | 383 |
411 Note: there are a variety of convenience functions to build a | 384 Note: there are a variety of convenience functions to build a |