comparison mercurial/cmdutil.py @ 9536:f04d17912441

cmdutil: templating keywords latesttag and latesttagdistance This can be used for referring to revisions in a reasonable meaningful, stable and monotonically increasing way, suitable for releases or builds directly from a repository. The latest tag is found by searching through untagged ancestors and finding the latest tagged ancestor based on tag date. The distance is found from the length of the longest path to the tagged revision. For example: hg log -l1 --template '{latesttag}+{latesttagdistance}\n' can return 1.3.1+197 This is mostly work by Gilles Moris <gilles.moris@free.fr>
author Mads Kiilerich <mads@kiilerich.com>
date Sat, 03 Oct 2009 18:31:20 +0200
parents ae88c721f916
children f57640bf10d4
comparison
equal deleted inserted replaced
9535:75d290db2df6 9536:f04d17912441
743 self.t = templater.templater(mapfile, {'formatnode': formatnode}, 743 self.t = templater.templater(mapfile, {'formatnode': formatnode},
744 cache={ 744 cache={
745 'parent': '{rev}:{node|formatnode} ', 745 'parent': '{rev}:{node|formatnode} ',
746 'manifest': '{rev}:{node|formatnode}', 746 'manifest': '{rev}:{node|formatnode}',
747 'filecopy': '{name} ({source})'}) 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 def use_template(self, t): 752 def use_template(self, t):
750 '''set template string to use''' 753 '''set template string to use'''
751 self.t.cache['changeset'] = t 754 self.t.cache['changeset'] = t
752 755
759 if self.ui.debugflag: 762 if self.ui.debugflag:
760 return [parents[0], self.repo['null']] 763 return [parents[0], self.repo['null']]
761 if parents[0].rev() >= ctx.rev() - 1: 764 if parents[0].rev() >= ctx.rev() - 1:
762 return [] 765 return []
763 return parents 766 return parents
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]
764 791
765 def _show(self, ctx, copies, props): 792 def _show(self, ctx, copies, props):
766 '''show a single changeset or file revision''' 793 '''show a single changeset or file revision'''
767 794
768 def showlist(name, values, plural=None, **args): 795 def showlist(name, values, plural=None, **args):
877 files += 1 904 files += 1
878 adds += i[1] 905 adds += i[1]
879 removes += i[2] 906 removes += i[2]
880 return '%s: +%s/-%s' % (files, adds, removes) 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 defprops = { 914 defprops = {
883 'author': ctx.user(), 915 'author': ctx.user(),
884 'branches': showbranches, 916 'branches': showbranches,
885 'date': ctx.date(), 917 'date': ctx.date(),
886 'desc': ctx.description().strip(), 918 'desc': ctx.description().strip(),
894 'parents': showparents, 926 'parents': showparents,
895 'rev': ctx.rev(), 927 'rev': ctx.rev(),
896 'tags': showtags, 928 'tags': showtags,
897 'extras': showextras, 929 'extras': showextras,
898 'diffstat': showdiffstat, 930 'diffstat': showdiffstat,
931 'latesttag': showlatesttag,
932 'latesttagdistance': showlatesttagdistance,
899 } 933 }
900 props = props.copy() 934 props = props.copy()
901 props.update(defprops) 935 props.update(defprops)
902 936
903 # find correct templates for current mode 937 # find correct templates for current mode