[PATCH] convert: make tags children of the nodes they tag

Alexis S. L. Carvalho alexis at cecm.usp.br
Wed Jul 11 20:10:18 CDT 2007


Thus spake Brendan Cully:
> # HG changeset patch
> # User Brendan Cully <brendan at kublai.com>
> # Date 1184141011 25200
> # Node ID 730206f6ee6570dd99a883bf3184ad89b415fc09
> # Parent  1f3742217a7689928becc04066c303a5329585bc
> convert: make tags children of the nodes they tag
> 
> They also have the same date and branch as the nodes they tag. One
> advantage of this scheme is that a clone -r branch will get the tags
> that belong on that branch and avoid those that don't (otherwise, many
> operations complain about invalid tags).

It also creates a repo that more closely resembles a regular hg repo.

> One regression is that deleted tags are not discovered when convert is
> run incrementally. This could be fixed in a second changeset if
> desired.

There's a similar problem with moved tags.


I like the idea, but before we apply this change, we have to correct the
handling of tags when converting merges.

Right now convert_mercurial never passes '.hgtags' to repo.rawcommit,
which means the new revision ends up inheriting the .hgtags from its
first parent, which means we can lose some tags during a merge.

With the current scheme this is not a huge problem because we readd the
tags at the end of the conversion session, but if we tag revisions as
soon as possible, we may end up losing them.

As an example, take a look at the attached tarball.  It contains a git
repo with a revision graph that looks like this:

         ---------- change foo -------
        /                             \
 add foo                               Merge branch 'boo'
        \                             /
         ---------   add bar   -------

"change foo" is tagged as tag1 and "add bar" is tagged as tag2.  Current
hg convert will give us a nice hg repo with tag1 and tag2 (but if you
convert every revision individually, the .hgtags from the "Merge branch
'boo'" revision will contain only tag1).  With this patch, we'll get a
repo with only tag1.

The right thing to do here would be to merge the .hgtags from both
parents, so that .hgtags from the merge revision has both tags.  The
tricky bit is avoiding too much unnecessary work if no .hgtags merge is
needed.

I have some code to merge .hgtags files (I'll post it in a bit) and I
think I know how to hook it into the convert process in an efficient
way (essentially using a subclass of localrepo and filelog and letting
filecommit decide if merging is needed - the actual merging would be
done by filelog.add).


Some comments on the patch:

> diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
> --- a/hgext/convert/hg.py
> +++ b/hgext/convert/hg.py
> @@ -69,6 +69,19 @@ class convert_mercurial(converter_sink):
>  
>          return p2
>  
> +    def puttag(self, tag, rev):
> +        ctx = self.repo.changectx(rev)
> +        extra = {}
> +        if ctx.branch():
> +            extra['branch'] = ctx.branch()
> +        date = '%d %d' % ctx.date()
> +        msg = 'imported tag %s' % tag
> +
> +        n = self.repo._tag(tag, ctx.node(), msg, False, 'convert-repo', date,
> +                           parent=ctx.node(), extra=extra)

This can be done later, but I think it'd be nice to use the same
standard "Added tag foobar for changeset 0123456789ab" message from hg
tag - and maybe some way to set the author would be nice, too...

> +
> +        return hg.hex(n)
> +
>      def puttags(self, tags):

We can remove the puttags method, no?  And update the classes in
common.py...

Alexis
-------------- next part --------------
A non-text attachment was scrubbed...
Name: git-repo.tar.gz
Type: application/octet-stream
Size: 7616 bytes
Desc: not available
Url : http://selenic.com/pipermail/mercurial-devel/attachments/20070711/139aa926/attachment.obj 


More information about the Mercurial-devel mailing list