761 cache={ |
761 cache={ |
762 'parent': '{rev}:{node|formatnode} ', |
762 'parent': '{rev}:{node|formatnode} ', |
763 'manifest': '{rev}:{node|formatnode}', |
763 'manifest': '{rev}:{node|formatnode}', |
764 'filecopy': '{name} ({source})', |
764 'filecopy': '{name} ({source})', |
765 'extra': '{key}={value|stringescape}'}) |
765 'extra': '{key}={value|stringescape}'}) |
766 # Cache mapping from rev to a tuple with tag date, tag |
766 self.cache = {} |
767 # distance and tag name |
|
768 self._latesttagcache = {-1: (0, 0, 'null')} |
|
769 |
767 |
770 def use_template(self, t): |
768 def use_template(self, t): |
771 '''set template string to use''' |
769 '''set template string to use''' |
772 self.t.cache['changeset'] = t |
770 self.t.cache['changeset'] = t |
773 |
771 |
781 return [parents[0], self.repo['null']] |
779 return [parents[0], self.repo['null']] |
782 if parents[0].rev() >= ctx.rev() - 1: |
780 if parents[0].rev() >= ctx.rev() - 1: |
783 return [] |
781 return [] |
784 return parents |
782 return parents |
785 |
783 |
786 def _latesttaginfo(self, rev): |
|
787 '''return date, distance and name for the latest tag of rev''' |
|
788 todo = [rev] |
|
789 while todo: |
|
790 rev = todo.pop() |
|
791 if rev in self._latesttagcache: |
|
792 continue |
|
793 ctx = self.repo[rev] |
|
794 tags = [t for t in ctx.tags() if self.repo.tagtype(t) == 'global'] |
|
795 if tags: |
|
796 self._latesttagcache[rev] = ctx.date()[0], 0, ':'.join(sorted(tags)) |
|
797 continue |
|
798 try: |
|
799 # The tuples are laid out so the right one can be found by comparison. |
|
800 pdate, pdist, ptag = max( |
|
801 self._latesttagcache[p.rev()] for p in ctx.parents()) |
|
802 except KeyError: |
|
803 # Cache miss - recurse |
|
804 todo.append(rev) |
|
805 todo.extend(p.rev() for p in ctx.parents()) |
|
806 continue |
|
807 self._latesttagcache[rev] = pdate, pdist + 1, ptag |
|
808 return self._latesttagcache[rev] |
|
809 |
|
810 def _show(self, ctx, copies, props): |
784 def _show(self, ctx, copies, props): |
811 '''show a single changeset or file revision''' |
785 '''show a single changeset or file revision''' |
812 |
786 |
813 showlist = templatekw.showlist |
787 showlist = templatekw.showlist |
814 |
788 |
818 return showlist(templ, 'parent', parents, **args) |
792 return showlist(templ, 'parent', parents, **args) |
819 |
793 |
820 def showcopies(repo, ctx, templ, **args): |
794 def showcopies(repo, ctx, templ, **args): |
821 c = [{'name': x[0], 'source': x[1]} for x in copies] |
795 c = [{'name': x[0], 'source': x[1]} for x in copies] |
822 return showlist(templ, 'file_copy', c, plural='file_copies', **args) |
796 return showlist(templ, 'file_copy', c, plural='file_copies', **args) |
823 |
|
824 def showlatesttag(repo, ctx, templ, **args): |
|
825 return self._latesttaginfo(ctx.rev())[2] |
|
826 def showlatesttagdistance(repo, ctx, templ, **args): |
|
827 return self._latesttaginfo(ctx.rev())[1] |
|
828 |
797 |
829 defprops = { |
798 defprops = { |
830 'file_copies': showcopies, |
799 'file_copies': showcopies, |
831 'parents': showparents, |
800 'parents': showparents, |
832 'latesttag': showlatesttag, |
|
833 'latesttagdistance': showlatesttagdistance, |
|
834 } |
801 } |
835 props = props.copy() |
802 props = props.copy() |
836 props.update(templatekw.keywords) |
803 props.update(templatekw.keywords) |
837 props.update(defprops) |
804 props.update(defprops) |
838 props['templ'] = self.t |
805 props['templ'] = self.t |
839 props['ctx'] = ctx |
806 props['ctx'] = ctx |
840 props['repo'] = self.repo |
807 props['repo'] = self.repo |
841 props['revcache'] = {} |
808 props['revcache'] = {} |
|
809 props['cache'] = self.cache |
842 |
810 |
843 # find correct templates for current mode |
811 # find correct templates for current mode |
844 |
812 |
845 tmplmodes = [ |
813 tmplmodes = [ |
846 (True, None), |
814 (True, None), |