##// END OF EJS Templates
cmdutil: add json style to log-like commands...
Matt Mackall -
r22427:bd159328 default
parent child Browse files
Show More
@@ -13,6 +13,7 b' import match as matchmod'
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
14 import changelog
14 import changelog
15 import bookmarks
15 import bookmarks
16 import encoding
16 import lock as lockmod
17 import lock as lockmod
17
18
18 def parsealiases(cmd):
19 def parsealiases(cmd):
@@ -1013,6 +1014,95 b' class changeset_printer(object):'
1013 parents = [parents[0]]
1014 parents = [parents[0]]
1014 return parents
1015 return parents
1015
1016
1017 class jsonchangeset(changeset_printer):
1018 '''format changeset information.'''
1019
1020 def __init__(self, ui, repo, matchfn, diffopts, buffered):
1021 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1022 self.cache = {}
1023 self._first = True
1024
1025 def close(self):
1026 if not self._first:
1027 self.ui.write("\n]\n")
1028 else:
1029 self.ui.write("[]\n")
1030
1031 def _show(self, ctx, copies, matchfn, props):
1032 '''show a single changeset or file revision'''
1033 hexnode = hex(ctx.node())
1034 rev = ctx.rev()
1035 j = encoding.jsonescape
1036
1037 if self._first:
1038 self.ui.write("[\n {")
1039 self._first = False
1040 else:
1041 self.ui.write(",\n {")
1042
1043 if self.ui.quiet:
1044 self.ui.write('\n "rev": %d' % rev)
1045 self.ui.write(',\n "node": "%s"' % hexnode)
1046 self.ui.write('\n }')
1047 return
1048
1049 self.ui.write('\n "rev": %d' % rev)
1050 self.ui.write(',\n "node": "%s"' % hexnode)
1051 self.ui.write(',\n "branch": "%s"' % j(ctx.branch()))
1052 self.ui.write(',\n "phase": "%s"' % ctx.phasestr())
1053 self.ui.write(',\n "user": "%s"' % j(ctx.user()))
1054 self.ui.write(',\n "date": [%d, %d]' % ctx.date())
1055 self.ui.write(',\n "desc": "%s"' % j(ctx.description()))
1056
1057 self.ui.write(',\n "bookmarks": [%s]' %
1058 ", ".join('"%s"' % j(b) for b in ctx.bookmarks()))
1059 self.ui.write(',\n "tags": [%s]' %
1060 ", ".join('"%s"' % j(t) for t in ctx.tags()))
1061 self.ui.write(',\n "parents": [%s]' %
1062 ", ".join('"%s"' % c.hex() for c in ctx.parents()))
1063
1064 if self.ui.debugflag:
1065 self.ui.write(',\n "manifest": "%s"' % hex(ctx.manifestnode()))
1066
1067 self.ui.write(',\n "extra": {%s}' %
1068 ", ".join('"%s": "%s"' % (j(k), j(v))
1069 for k, v in ctx.extra().items()))
1070
1071 files = ctx.status(ctx.p1())
1072 self.ui.write(',\n "modified": [%s]' %
1073 ", ".join('"%s"' % j(f) for f in files[0]))
1074 self.ui.write(',\n "added": [%s]' %
1075 ", ".join('"%s"' % j(f) for f in files[1]))
1076 self.ui.write(',\n "removed": [%s]' %
1077 ", ".join('"%s"' % j(f) for f in files[2]))
1078
1079 elif self.ui.verbose:
1080 self.ui.write(',\n "files": [%s]' %
1081 ", ".join('"%s"' % j(f) for f in ctx.files()))
1082
1083 if copies:
1084 self.ui.write(',\n "copies": {%s}' %
1085 ", ".join('"%s": %s' % (j(k), j(copies[k]))
1086 for k in copies))
1087
1088 matchfn = self.matchfn
1089 if matchfn:
1090 stat = self.diffopts.get('stat')
1091 diff = self.diffopts.get('patch')
1092 diffopts = patch.diffopts(self.ui, self.diffopts)
1093 node, prev = ctx.node(), ctx.p1().node()
1094 if stat:
1095 self.ui.pushbuffer()
1096 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1097 match=matchfn, stat=True)
1098 self.ui.write(',\n "diffstat": "%s"' % j(self.ui.popbuffer()))
1099 if diff:
1100 self.ui.pushbuffer()
1101 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1102 match=matchfn, stat=False)
1103 self.ui.write(',\n "diff": "%s"' % j(self.ui.popbuffer()))
1104
1105 self.ui.write("\n }")
1016
1106
1017 class changeset_templater(changeset_printer):
1107 class changeset_templater(changeset_printer):
1018 '''format changeset information.'''
1108 '''format changeset information.'''
@@ -1195,6 +1285,9 b' def show_changeset(ui, repo, opts, buffe'
1195 if opts.get('patch') or opts.get('stat'):
1285 if opts.get('patch') or opts.get('stat'):
1196 matchfn = scmutil.matchall(repo)
1286 matchfn = scmutil.matchall(repo)
1197
1287
1288 if opts.get('template') == 'json':
1289 return jsonchangeset(ui, repo, matchfn, opts, buffered)
1290
1198 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1291 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1199
1292
1200 if not tmpl and not mapfile:
1293 if not tmpl and not mapfile:
@@ -468,6 +468,350 b' Test xml styles:'
468 </log>
468 </log>
469
469
470
470
471 Test JSON style:
472
473 $ hg log -k nosuch -Tjson
474 []
475
476 $ hg log -qr . -Tjson
477 [
478 {
479 "rev": 8,
480 "node": "95c24699272ef57d062b8bccc32c878bf841784a"
481 }
482 ]
483
484 $ hg log -vpr . -Tjson --stat
485 [
486 {
487 "rev": 8,
488 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
489 "branch": "default",
490 "phase": "draft",
491 "user": "test",
492 "date": [1577872860, 0],
493 "desc": "third",
494 "bookmarks": [],
495 "tags": ["tip"],
496 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
497 "files": ["fourth", "second", "third"],
498 "diffstat": " fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n",
499 "diff": "diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n"
500 }
501 ]
502
503 $ hg log -T json
504 [
505 {
506 "rev": 8,
507 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
508 "branch": "default",
509 "phase": "draft",
510 "user": "test",
511 "date": [1577872860, 0],
512 "desc": "third",
513 "bookmarks": [],
514 "tags": ["tip"],
515 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"]
516 },
517 {
518 "rev": 7,
519 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
520 "branch": "default",
521 "phase": "draft",
522 "user": "User Name <user@hostname>",
523 "date": [1000000, 0],
524 "desc": "second",
525 "bookmarks": [],
526 "tags": [],
527 "parents": ["0000000000000000000000000000000000000000"]
528 },
529 {
530 "rev": 6,
531 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
532 "branch": "default",
533 "phase": "draft",
534 "user": "person",
535 "date": [1500001, 0],
536 "desc": "merge",
537 "bookmarks": [],
538 "tags": [],
539 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"]
540 },
541 {
542 "rev": 5,
543 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
544 "branch": "default",
545 "phase": "draft",
546 "user": "person",
547 "date": [1500000, 0],
548 "desc": "new head",
549 "bookmarks": [],
550 "tags": [],
551 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
552 },
553 {
554 "rev": 4,
555 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
556 "branch": "foo",
557 "phase": "draft",
558 "user": "person",
559 "date": [1400000, 0],
560 "desc": "new branch",
561 "bookmarks": [],
562 "tags": [],
563 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"]
564 },
565 {
566 "rev": 3,
567 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
568 "branch": "default",
569 "phase": "draft",
570 "user": "person",
571 "date": [1300000, 0],
572 "desc": "no user, no domain",
573 "bookmarks": [],
574 "tags": [],
575 "parents": ["97054abb4ab824450e9164180baf491ae0078465"]
576 },
577 {
578 "rev": 2,
579 "node": "97054abb4ab824450e9164180baf491ae0078465",
580 "branch": "default",
581 "phase": "draft",
582 "user": "other@place",
583 "date": [1200000, 0],
584 "desc": "no person",
585 "bookmarks": [],
586 "tags": [],
587 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"]
588 },
589 {
590 "rev": 1,
591 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
592 "branch": "default",
593 "phase": "draft",
594 "user": "A. N. Other <other@place>",
595 "date": [1100000, 0],
596 "desc": "other 1\nother 2\n\nother 3",
597 "bookmarks": [],
598 "tags": [],
599 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"]
600 },
601 {
602 "rev": 0,
603 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
604 "branch": "default",
605 "phase": "draft",
606 "user": "User Name <user@hostname>",
607 "date": [1000000, 0],
608 "desc": "line 1\nline 2",
609 "bookmarks": [],
610 "tags": [],
611 "parents": ["0000000000000000000000000000000000000000"]
612 }
613 ]
614
615 $ hg heads -v -Tjson
616 [
617 {
618 "rev": 8,
619 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
620 "branch": "default",
621 "phase": "draft",
622 "user": "test",
623 "date": [1577872860, 0],
624 "desc": "third",
625 "bookmarks": [],
626 "tags": ["tip"],
627 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
628 "files": ["fourth", "second", "third"]
629 },
630 {
631 "rev": 6,
632 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
633 "branch": "default",
634 "phase": "draft",
635 "user": "person",
636 "date": [1500001, 0],
637 "desc": "merge",
638 "bookmarks": [],
639 "tags": [],
640 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
641 "files": []
642 },
643 {
644 "rev": 4,
645 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
646 "branch": "foo",
647 "phase": "draft",
648 "user": "person",
649 "date": [1400000, 0],
650 "desc": "new branch",
651 "bookmarks": [],
652 "tags": [],
653 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
654 "files": []
655 }
656 ]
657
658 $ hg log --debug -Tjson
659 [
660 {
661 "rev": 8,
662 "node": "95c24699272ef57d062b8bccc32c878bf841784a",
663 "branch": "default",
664 "phase": "draft",
665 "user": "test",
666 "date": [1577872860, 0],
667 "desc": "third",
668 "bookmarks": [],
669 "tags": ["tip"],
670 "parents": ["29114dbae42b9f078cf2714dbe3a86bba8ec7453"],
671 "manifest": "94961b75a2da554b4df6fb599e5bfc7d48de0c64",
672 "extra": {"branch": "default"},
673 "modified": [],
674 "added": ["second"],
675 "removed": ["fourth", "third"]
676 },
677 {
678 "rev": 7,
679 "node": "29114dbae42b9f078cf2714dbe3a86bba8ec7453",
680 "branch": "default",
681 "phase": "draft",
682 "user": "User Name <user@hostname>",
683 "date": [1000000, 0],
684 "desc": "second",
685 "bookmarks": [],
686 "tags": [],
687 "parents": ["0000000000000000000000000000000000000000"],
688 "manifest": "f2dbc354b94e5ec0b4f10680ee0cee816101d0bf",
689 "extra": {"branch": "default"},
690 "modified": [],
691 "added": [],
692 "removed": ["second"]
693 },
694 {
695 "rev": 6,
696 "node": "d41e714fe50d9e4a5f11b4d595d543481b5f980b",
697 "branch": "default",
698 "phase": "draft",
699 "user": "person",
700 "date": [1500001, 0],
701 "desc": "merge",
702 "bookmarks": [],
703 "tags": [],
704 "parents": ["13207e5a10d9fd28ec424934298e176197f2c67f", "bbe44766e73d5f11ed2177f1838de10c53ef3e74"],
705 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
706 "extra": {"branch": "default"},
707 "modified": [],
708 "added": [],
709 "removed": []
710 },
711 {
712 "rev": 5,
713 "node": "13207e5a10d9fd28ec424934298e176197f2c67f",
714 "branch": "default",
715 "phase": "draft",
716 "user": "person",
717 "date": [1500000, 0],
718 "desc": "new head",
719 "bookmarks": [],
720 "tags": [],
721 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
722 "manifest": "4dc3def4f9b4c6e8de820f6ee74737f91e96a216",
723 "extra": {"branch": "default"},
724 "modified": [],
725 "added": [],
726 "removed": ["d"]
727 },
728 {
729 "rev": 4,
730 "node": "bbe44766e73d5f11ed2177f1838de10c53ef3e74",
731 "branch": "foo",
732 "phase": "draft",
733 "user": "person",
734 "date": [1400000, 0],
735 "desc": "new branch",
736 "bookmarks": [],
737 "tags": [],
738 "parents": ["10e46f2dcbf4823578cf180f33ecf0b957964c47"],
739 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
740 "extra": {"branch": "foo"},
741 "modified": [],
742 "added": [],
743 "removed": []
744 },
745 {
746 "rev": 3,
747 "node": "10e46f2dcbf4823578cf180f33ecf0b957964c47",
748 "branch": "default",
749 "phase": "draft",
750 "user": "person",
751 "date": [1300000, 0],
752 "desc": "no user, no domain",
753 "bookmarks": [],
754 "tags": [],
755 "parents": ["97054abb4ab824450e9164180baf491ae0078465"],
756 "manifest": "cb5a1327723bada42f117e4c55a303246eaf9ccc",
757 "extra": {"branch": "default"},
758 "modified": ["c"],
759 "added": [],
760 "removed": []
761 },
762 {
763 "rev": 2,
764 "node": "97054abb4ab824450e9164180baf491ae0078465",
765 "branch": "default",
766 "phase": "draft",
767 "user": "other@place",
768 "date": [1200000, 0],
769 "desc": "no person",
770 "bookmarks": [],
771 "tags": [],
772 "parents": ["b608e9d1a3f0273ccf70fb85fd6866b3482bf965"],
773 "manifest": "6e0e82995c35d0d57a52aca8da4e56139e06b4b1",
774 "extra": {"branch": "default"},
775 "modified": [],
776 "added": [],
777 "removed": ["c"]
778 },
779 {
780 "rev": 1,
781 "node": "b608e9d1a3f0273ccf70fb85fd6866b3482bf965",
782 "branch": "default",
783 "phase": "draft",
784 "user": "A. N. Other <other@place>",
785 "date": [1100000, 0],
786 "desc": "other 1\nother 2\n\nother 3",
787 "bookmarks": [],
788 "tags": [],
789 "parents": ["1e4e1b8f71e05681d422154f5421e385fec3454f"],
790 "manifest": "4e8d705b1e53e3f9375e0e60dc7b525d8211fe55",
791 "extra": {"branch": "default"},
792 "modified": [],
793 "added": [],
794 "removed": ["b"]
795 },
796 {
797 "rev": 0,
798 "node": "1e4e1b8f71e05681d422154f5421e385fec3454f",
799 "branch": "default",
800 "phase": "draft",
801 "user": "User Name <user@hostname>",
802 "date": [1000000, 0],
803 "desc": "line 1\nline 2",
804 "bookmarks": [],
805 "tags": [],
806 "parents": ["0000000000000000000000000000000000000000"],
807 "manifest": "a0c8bcbbb45c63b90b70ad007bf38961f64f2af0",
808 "extra": {"branch": "default"},
809 "modified": [],
810 "added": [],
811 "removed": ["a"]
812 }
813 ]
814
471 Error if style not readable:
815 Error if style not readable:
472
816
473 #if unix-permissions no-root
817 #if unix-permissions no-root
General Comments 0
You need to be logged in to leave comments. Login now