Versioning builds from repos

Mads Kiilerich mads at kiilerich.com
Sun Jul 12 19:37:46 CDT 2009


Some comments to the patch:

Gilles Moris wrote, On 07/12/2009 06:42 PM:
> On Thu July 9 2009 18:18:28 Matt Mackall wrote:
>    
>> True.
>>
>> It's still preferable to have this as a separate template element (ie
>> {lasttagdistance}) so that people who don't need a monotonically
>> increasing number can skip it.
>>
>>      
> Is it in better way now:
> - defined the new {lasttag} and {lasttagdistance} templates
> - exited most of the code as a method instead of a nested function
> - kept anyway 2 functions to avoid the last tag map to be computed if not
>    requested. BTW, performance penalty is not that large for the mercurial repo.
>    I need it for distance to clean up the display anyway.
> - excluded the MQ tags (users don't want to see their top patch to appear here)
>    Do somebody knows a better method to extract only core tags ?
> - took as assumption that the repo can't change during the changeset_templater
>    life time. OK?
>
> Regards.
> Gilles.
>
>
> # HG changeset patch
> # User Gilles Moris<gilles.moris at free.fr>
> # Date 1247087563 -7200
> # Node ID 9f96016e8be12920ebe1c756ffc254375bca3a74
> # Parent  574ab9a3ad4dfb66ff5bf3ffb933db7a89b7ba08
> templates: add {lasttag} and {lasttagdistance} templates.
>
> Useful to build nightly version names and see on which tag a rev is based on.
>
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -741,6 +741,43 @@
>                                            'manifest': '{rev}:{node|formatnode}',
>                                            'filecopy': '{name} ({source})'})
>
> +    @util.propertycache
> +    def ltmap(self):
> +        '''get an array[rev] of latest tag tuple, each tuple being
> +        (date of the latest tag, the [first] tag, distance to that tag).
> +        Exclude "tip" and MQ tags from the search.
> +        '''
> +        defvalue = 0, '', -1
> +        ltmap = [defvalue] * len(self.repo)
>    

Using the methods name in local scope seems quite confusing to me.

> +
> +        try:
> +            qbase = self.repo['qbase'].rev()
> +            qtip = self.repo['qtip'].rev()
> +            excltags = frozenset(['tip', 'qparent'])
> +        except error.RepoError:
> +            excltags = ['tip']
> +            qbase = qtip = -1
>    

We probably don't want any mq references in core Mercurial. If special 
handling of mq still is needed then mq should monkey-patch it somehow.

> +
> +        for r in range(len(self.repo)):
>    

This always loops over all revisions, even though we typically only 
needs this information for one changeset, and once the tag is found we 
don't have to go further back in history. Could the traversal perhaps be 
done on demand?

> +            ctx = self.repo[r]
> +
> +            tags = [t for t in ctx.tags() if t not in excltags]
> +            if tags and not (r>= qbase and r<= qtip):
>    

This seems to be a very clever way to skip all tags after qbase. 
Couldn't it be made simpler and more explicit? Perhaps by letting qbase 
default to sys.maxint?

> +                ltmap[r] = ctx.date(), tags[0], 0
> +            else:
> +                # trick: use tuple comparison to sort by latest date first
> +                # and if the dates (and by construction also the tag) are
> +                # equal, by longuest path.
>    

Dates shouldn't be used for anything; they are not guaranteed to be 
monotonic.

Matt suggested the name "lasttag", but defined it as "nearest tag". That 
is also a strong hint that "nearesttag" might be a better name.

"Nearest tag" hints at a breath-first search through ancestors, stopping 
at the first tagged node.

IMHO: If there is more than one possible nearest tag candidate then 
there is no really good way to decide which one to use. Always using the 
tipmost tagged ancestor would be fine (and simple and efficient) too.

> +                lasttag = reduce(max,
> +                                 [ltmap[p.rev()] for p in ctx.parents()],
> +                                 defvalue)
> +                ldate, ltag, ldist = lasttag
> +                # if no previous tag, nothing to do (leave default value)
> +                if ltag:
> +                    ltmap[r] = ldate, ltag, ldist + 1
> +
> +        return ltmap
> +
>       def use_template(self, t):
>           '''set template string to use'''
>           self.t.cache['changeset'] = t
> @@ -874,6 +911,15 @@
>                   removes += i[2]
>               return '%s: +%s/-%s' % (files, adds, removes)
>
> +        def showlasttag(**args):
> +            return self.ltmap[ctx.rev()][1]
> +        def showlasttagdistance(**args):
> +            dist = self.ltmap[ctx.rev()][2]
> +            if dist>= 0:
> +                return dist
> +            else:
> +                return ''
> +
>           defprops = {
>               'author': ctx.user(),
>               'branches': showbranches,
> @@ -891,6 +937,8 @@
>               'tags': showtags,
>               'extras': showextras,
>               'diffstat': showdiffstat,
> +            'lasttag': showlasttag,
> +            'lasttagdistance': showlasttagdistance,
>               }
>           props = props.copy()
>           props.update(defprops)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>    



More information about the Mercurial-devel mailing list