Versioning builds from repos
Dirkjan Ochtman
dirkjan at ochtman.nl
Thu Jul 9 20:00:27 UTC 2009
On Wed, Jul 8, 2009 at 23:34, Gilles Moris<gilles.moris at free.fr> wrote:
> I worked back on a patch using templates, which the crew seems looking for.
> So to get what you want with my patch, you would do:
> hg parent --template '{basedontags|stringify|strip}-{node|short}\n'
>
> Note that the template is actually returning a list. This is the case for
> that configuration:
>
> o-o-a-o-x
> \ /
> \o-b-o/
>
> If a and b are tags, then I return both tags for x, because I consider x
> as based on the two branches. I am pretty sure it does not happen for
> mercurial given the tagging strategy, but it can happen on other projects.
> In this case, we need also the 'first' template filter from Paolo Bonzini:
> http://www.selenic.com/pipermail/mercurial-devel/2009-June/013329.html
>
> I changed my implementation to be constant time whatever the number of
> changesets looked up. This is not necessary for this workflow but necessary
> if somebody has the idea to use it with hg log on the whole repo.
>
> Comments before I continue to work on that ?
>
>
> # HG changeset patch
> # User Gilles Moris <gilles.moris at free.fr>
> # Date 1247087563 -7200
> # Node ID 84d8e4818c6038a07eba9db660ead8983a91556c
> # Parent de29540d44ecce9a13df9c3bf1a3c93d30dc6c20
> templates: add a {basedontags}
>
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -735,11 +735,13 @@
> def __init__(self, ui, repo, patch, diffopts, mapfile, buffered):
> changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
> formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
> + self.basedonmap = None
> self.t = templater.templater(mapfile, {'formatnode': formatnode},
> cache={
> 'parent': '{rev}:{node|formatnode} ',
> 'manifest': '{rev}:{node|formatnode}',
> - 'filecopy': '{name} ({source})'})
> + 'filecopy': '{name} ({source})',
> + 'basedontag': '{basetag}+{basedistance} '})
>
> def use_template(self, t):
> '''set template string to use'''
> @@ -874,6 +876,42 @@
> removes += i[2]
> return '%s: +%s/-%s' % (files, adds, removes)
>
> + def computebasedon():
> + bmap = [{}] * len(self.repo)
> + deps = {}
> +
> + for r in xrange(len(self.repo)):
> + ctx = self.repo[r]
> +
> + # get longuest path to changeset with tags
> + bmap[r] = {}
> + for p in ctx.parents():
> + for tr, td in bmap[p.rev()].iteritems():
> + if tr not in bmap[r] or td + 1 > bmap[r][tr]:
> + bmap[r][tr] = td + 1
> +
> + # filter out descendant
> + for rr in bmap[r].keys():
> + for dr in deps[rr]:
> + if dr in bmap[r].keys():
> + del bmap[r][dr]
> +
> + if ctx.tags() and ctx.rev() != len(self.repo) - 1:
> + # if some tags found, record their descendant
> + deps[r] = list(bmap[r].keys())
> + bmap[r] = {r: 0}
> +
> + return bmap
> +
> + def showbasedontags(**args):
> + if not self.basedonmap:
> + self.basedonmap = computebasedon()
> + bot = [ (str(td), '='.join(self.repo[tr].tags()))
> + for tr, td in self.basedonmap[ctx.rev()].iteritems() ]
> + bot.sort()
> + bot = [ { 'basedistance': td, 'basetag': tr } for td, tr in bot ]
> + return showlist('basedontag', bot, **args)
> +
> defprops = {
> 'author': ctx.user(),
> 'branches': showbranches,
> @@ -891,6 +929,7 @@
> 'tags': showtags,
> 'extras': showextras,
> 'diffstat': showdiffstat,
> + 'basedontags': showbasedontags,
> }
> props = props.copy()
> props.update(defprops)
I still think adding this code in that method as another nested
function is a bad idea. The function is way too cluttered already.
Even doing a separate closure would be better, IMO.
Cheers,
Dirkjan
More information about the Mercurial-devel
mailing list