Show More
@@ -745,6 +745,9 b' class changeset_templater(changeset_prin' | |||
|
745 | 745 | 'parent': '{rev}:{node|formatnode} ', |
|
746 | 746 | 'manifest': '{rev}:{node|formatnode}', |
|
747 | 747 | 'filecopy': '{name} ({source})'}) |
|
748 | # Cache mapping from rev to a tuple with tag date, tag | |
|
749 | # distance and tag name | |
|
750 | self._latesttagcache = {-1: (0, 0, 'null')} | |
|
748 | 751 | |
|
749 | 752 | def use_template(self, t): |
|
750 | 753 | '''set template string to use''' |
@@ -762,6 +765,30 b' class changeset_templater(changeset_prin' | |||
|
762 | 765 | return [] |
|
763 | 766 | return parents |
|
764 | 767 | |
|
768 | def _latesttaginfo(self, rev): | |
|
769 | '''return date, distance and name for the latest tag of rev''' | |
|
770 | todo = [rev] | |
|
771 | while todo: | |
|
772 | rev = todo.pop() | |
|
773 | if rev in self._latesttagcache: | |
|
774 | continue | |
|
775 | ctx = self.repo[rev] | |
|
776 | tags = [t for t in ctx.tags() if self.repo.tagtype(t) == 'global'] | |
|
777 | if tags: | |
|
778 | self._latesttagcache[rev] = ctx.date()[0], 0, ':'.join(sorted(tags)) | |
|
779 | continue | |
|
780 | try: | |
|
781 | # The tuples are laid out so the right one can be found by comparison. | |
|
782 | pdate, pdist, ptag = max( | |
|
783 | self._latesttagcache[p.rev()] for p in ctx.parents()) | |
|
784 | except KeyError: | |
|
785 | # Cache miss - recurse | |
|
786 | todo.append(rev) | |
|
787 | todo.extend(p.rev() for p in ctx.parents()) | |
|
788 | continue | |
|
789 | self._latesttagcache[rev] = pdate, pdist + 1, ptag | |
|
790 | return self._latesttagcache[rev] | |
|
791 | ||
|
765 | 792 | def _show(self, ctx, copies, props): |
|
766 | 793 | '''show a single changeset or file revision''' |
|
767 | 794 | |
@@ -879,6 +906,11 b' class changeset_templater(changeset_prin' | |||
|
879 | 906 | removes += i[2] |
|
880 | 907 | return '%s: +%s/-%s' % (files, adds, removes) |
|
881 | 908 | |
|
909 | def showlatesttag(**args): | |
|
910 | return self._latesttaginfo(ctx.rev())[2] | |
|
911 | def showlatesttagdistance(**args): | |
|
912 | return self._latesttaginfo(ctx.rev())[1] | |
|
913 | ||
|
882 | 914 | defprops = { |
|
883 | 915 | 'author': ctx.user(), |
|
884 | 916 | 'branches': showbranches, |
@@ -896,6 +928,8 b' class changeset_templater(changeset_prin' | |||
|
896 | 928 | 'tags': showtags, |
|
897 | 929 | 'extras': showextras, |
|
898 | 930 | 'diffstat': showdiffstat, |
|
931 | 'latesttag': showlatesttag, | |
|
932 | 'latesttagdistance': showlatesttagdistance, | |
|
899 | 933 | } |
|
900 | 934 | props = props.copy() |
|
901 | 935 | props.update(defprops) |
@@ -393,6 +393,9 b' PYTHONPATH' | |||
|
393 | 393 | number. |
|
394 | 394 | :tags: List of strings. Any tags associated with the |
|
395 | 395 | changeset. |
|
396 | :latesttag: String. Most recent global tag in the ancestors of this | |
|
397 | changeset. | |
|
398 | :latesttagdistance: Integer. Longest path to the latest tag. | |
|
396 | 399 | |
|
397 | 400 | The "date" keyword does not produce human-readable output. If you |
|
398 | 401 | want to use a date in your output, you can use a filter to process |
@@ -127,4 +127,49 b" echo '# error on syntax'" | |||
|
127 | 127 | echo 'x = "f' >> t |
|
128 | 128 | hg log |
|
129 | 129 | |
|
130 | cd .. | |
|
131 | ||
|
132 | echo '# latesttag' | |
|
133 | hg init latesttag | |
|
134 | cd latesttag | |
|
135 | ||
|
136 | echo a > file | |
|
137 | hg ci -Am a -d '0 0' | |
|
138 | ||
|
139 | echo b >> file | |
|
140 | hg ci -m b -d '1 0' | |
|
141 | ||
|
142 | echo c >> head1 | |
|
143 | hg ci -Am h1c -d '2 0' | |
|
144 | ||
|
145 | hg update -q 1 | |
|
146 | echo d >> head2 | |
|
147 | hg ci -Am h2d -d '3 0' | |
|
148 | ||
|
149 | echo e >> head2 | |
|
150 | hg ci -m h2e -d '4 0' | |
|
151 | ||
|
152 | hg merge -q | |
|
153 | hg ci -m merge -d '5 0' | |
|
154 | ||
|
155 | echo '# No tag set' | |
|
156 | hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' | |
|
157 | ||
|
158 | echo '# one common tag: longuest path wins' | |
|
159 | hg tag -r 1 -m t1 -d '6 0' t1 | |
|
160 | hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' | |
|
161 | ||
|
162 | echo '# one ancestor tag: more recent wins' | |
|
163 | hg tag -r 2 -m t2 -d '7 0' t2 | |
|
164 | hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' | |
|
165 | ||
|
166 | echo '# two branch tags: more recent wins' | |
|
167 | hg tag -r 3 -m t3 -d '8 0' t3 | |
|
168 | hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' | |
|
169 | ||
|
170 | echo '# merged tag overrides' | |
|
171 | hg tag -r 5 -m t5 -d '9 0' t5 | |
|
172 | hg tag -r 3 -m at3 -d '10 0' at3 | |
|
173 | hg log --template '{rev}: {latesttag}+{latesttagdistance}\n' | |
|
174 | ||
|
130 | 175 | echo '# done' |
@@ -672,4 +672,55 b' 1e4e1b8f71e0' | |||
|
672 | 672 | 1e4e1b8f71e05681d422154f5421e385fec3454f |
|
673 | 673 | # error on syntax |
|
674 | 674 | abort: t:3: unmatched quotes |
|
675 | # latesttag | |
|
676 | adding file | |
|
677 | adding head1 | |
|
678 | adding head2 | |
|
679 | created new head | |
|
680 | # No tag set | |
|
681 | 5: null+5 | |
|
682 | 4: null+4 | |
|
683 | 3: null+3 | |
|
684 | 2: null+3 | |
|
685 | 1: null+2 | |
|
686 | 0: null+1 | |
|
687 | # one common tag: longuest path wins | |
|
688 | 6: t1+4 | |
|
689 | 5: t1+3 | |
|
690 | 4: t1+2 | |
|
691 | 3: t1+1 | |
|
692 | 2: t1+1 | |
|
693 | 1: t1+0 | |
|
694 | 0: null+1 | |
|
695 | # one ancestor tag: more recent wins | |
|
696 | 7: t2+3 | |
|
697 | 6: t2+2 | |
|
698 | 5: t2+1 | |
|
699 | 4: t1+2 | |
|
700 | 3: t1+1 | |
|
701 | 2: t2+0 | |
|
702 | 1: t1+0 | |
|
703 | 0: null+1 | |
|
704 | # two branch tags: more recent wins | |
|
705 | 8: t3+5 | |
|
706 | 7: t3+4 | |
|
707 | 6: t3+3 | |
|
708 | 5: t3+2 | |
|
709 | 4: t3+1 | |
|
710 | 3: t3+0 | |
|
711 | 2: t2+0 | |
|
712 | 1: t1+0 | |
|
713 | 0: null+1 | |
|
714 | # merged tag overrides | |
|
715 | 10: t5+5 | |
|
716 | 9: t5+4 | |
|
717 | 8: t5+3 | |
|
718 | 7: t5+2 | |
|
719 | 6: t5+1 | |
|
720 | 5: t5+0 | |
|
721 | 4: at3:t3+1 | |
|
722 | 3: at3:t3+0 | |
|
723 | 2: t2+0 | |
|
724 | 1: t1+0 | |
|
725 | 0: null+1 | |
|
675 | 726 | # done |
General Comments 0
You need to be logged in to leave comments.
Login now