[ANN] tagmerge - an extension for merging .hgtags

Qi Yang qi.yang137 at gmail.com
Thu Feb 4 17:37:46 CST 2010


Thanks for the feedback Greg, I will look into the senario you provided, as
well as dig into localrepo.py and tags.py.

>> def pickmergetool(ui):
>>     '''pick merge tool for merging conflict: pick the highest priority
one
>> or use simple merge if there are no other merge tools'''
>>     tools = {}
>>     for k,v in ui.configitems("merge-tools"):
>>         toolname = k.split('.')[0]
>>         if toolname not in tools:
>>             tools[toolname] = int(_toolstr(ui, toolname, "priority",
"0"))
>>     if len(tools) == 0 or toolname == 'tagmerge':
>>         ui.debug("simplemerge will be used\n")
>>         return None
>>     tools = sorted([(-p,t) for t,p in tools.items()])
>>     priority, pickedtool = tools[0]
>>     ui.debug("Pick merge-tool %s" % (pickedtool))

>Isn't this logic already implemented somewhere in core Mercurial?  If
>it's not available to you in a reusable form, please submit a
>refactoring patch to correct that.

filemerge.py has something similar. but it is too complicated to totally use
it (checks symlink and binary). So I just wrote a simpler version based on
it. Should I try to use it?

Thanks,
Wendy

On Thu, Feb 4, 2010 at 9:30 AM, Greg Ward <greg-hg at gerg.ca> wrote:

> On Thu, Feb 4, 2010 at 12:30 AM, Qi Yang <qi.yang137 at gmail.com> wrote:
> > The following is the link to an extension I wrote for merging .hgtags
> file.
>
> Actually, it's not an extension.  It's a script.
>
> > https://q6yang@bitbucket.org/q6yang/tagmerge/
>
> There are a bunch of code style issues: long lines, trailing
> whitespace, etc.  Please run Matt's check-code.py script on your
> script.  check-code.py uses the filename to know what checks to apply,
> so you need to fool it, e.g.
>
>  ln -s tagmerge tagmerge.py
>  ~/src/hg-crew/contrib/check-code.py tagmerge.py
>
> Now to the real stuff:
>
> > def readtags(filename):
> >    '''parsing .hgtags file'''
> >     tags = {}
> >     with open(filename) as f:
> >          for line in f.readlines():
> >              tagid, tagname = line.split(" ")
> >              tags[tagname.strip()] = tagid
> >     return tags
>
> That won't work.  You cannot simply store .hgtags in a dictionary.
> Tag names can be repeated and order matters.  Play around with
> deleting and moving tags to see how that works:
>
>  hg tag -r 5 foo
>  hg tag -f -r 7 foo
>  hg tag --remove foo
>  hg tag -r 4 foo
>
> The resulting .hgtags looks very strange... until you think about what
> happens when you merge two .hgtags that have had similar games played.
>
> If it's any consolation, I made the exact same mistake around a year
> ago, when I posted my naive attempt at a tag-merging script.  Since
> then, Matt cunningly tricked me into becoming an .hgtags expert, so
> now I get to handle these sorts of things.  ;-)
>
> See mercurial/tags.py for code that understands how to read tags.  You
> probably want to reuse _readtags().
>
> IMHO this is something that should be improved in core Mercurial.  I
> think your ultimate goal should be a patch to mercurial/tags.py with
> all the tricky tag-merging logic, and then a front-end script in
> contrib/.  For now, keeping things in a little standalone script is
> probably the right thing to do.  Once that works it should be clear
> what belongs in tags.py.
>
> Another comment:
>
> > def pickmergetool(ui):
> >     '''pick merge tool for merging conflict: pick the highest priority
> one
> > or use simple merge if there are no other merge tools'''
> >     tools = {}
> >     for k,v in ui.configitems("merge-tools"):
> >         toolname = k.split('.')[0]
> >         if toolname not in tools:
> >             tools[toolname] = int(_toolstr(ui, toolname, "priority",
> "0"))
> >     if len(tools) == 0 or toolname == 'tagmerge':
> >         ui.debug("simplemerge will be used\n")
> >         return None
> >     tools = sorted([(-p,t) for t,p in tools.items()])
> >     priority, pickedtool = tools[0]
> >     ui.debug("Pick merge-tool %s" % (pickedtool))
>
> Isn't this logic already implemented somewhere in core Mercurial?  If
> it's not available to you in a reusable form, please submit a
> refactoring patch to correct that.
>
> > def writenewtags(filename, newtags):
> >     '''write non-local tags to the local .hgtags file'''
> >     with open(filename, 'r+') as f:
> >         for line in f.readlines():
> >             tagid, tagname = line.split(" ")
> >             for itemtagname, itemtagid in newtags.items():
> >                 if tagid == itemtagid and tagname != itemtagname:
> >                     f.write(itemtagid + ' ' + itemtagname)
> >                     break
> >         f.write('\n')
>
> And this is buried deep in localrepo.py.  It should probably be
> factored out to tags.py for reusability.  Please submit another
> refactoring patch for that!
>
> Thanks!
>
> Greg
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20100204/62408790/attachment.htm>


More information about the Mercurial-devel mailing list