# HG changeset patch # User Pierre-Yves David # Date 1490688895 -7200 # Node ID fe9c4d61460039dc884ab32fa4283b9ab0061e17 # Parent b36318e6d2ef7a351e4e62788105a10749b962d1 track-tags: compute the actual differences between tags pre/post transaction We now compute the proper actuall differences between tags before and after the transaction. This catch a couple of false positives in the tests. The compute the full difference since we are about to make this data available to hooks in the next changeset. diff -r b36318e6d2ef -r fe9c4d614600 mercurial/localrepo.py --- a/mercurial/localrepo.py Tue Mar 28 06:38:09 2017 +0200 +++ b/mercurial/localrepo.py Tue Mar 28 10:14:55 2017 +0200 @@ -1028,7 +1028,8 @@ newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads) # notes: we compare lists here. # As we do it only once buiding set would not be cheaper - if oldfnodes != newfnodes: + changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes) + if changes: tr2.hookargs['tag_moved'] = '1' def validate(tr2): """will run pre-closing hooks""" diff -r b36318e6d2ef -r fe9c4d614600 mercurial/tags.py --- a/mercurial/tags.py Tue Mar 28 06:38:09 2017 +0200 +++ b/mercurial/tags.py Tue Mar 28 10:14:55 2017 +0200 @@ -90,6 +90,45 @@ fnodes = _filterfnodes(fnodes, nodes) return fnodes +def _nulltonone(value): + """convert nullid to None + + For tag value, nullid means "deleted". This small utility function helps + translating that to None.""" + if value == nullid: + return None + return value + +def difftags(ui, repo, oldfnodes, newfnodes): + """list differences between tags expressed in two set of file-nodes + + The list contains entries in the form: (tagname, oldvalue, new value). + None is used to expressed missing value: + ('foo', None, 'abcd') is a new tag, + ('bar', 'ef01', None) is a deletion, + ('baz', 'abcd', 'ef01') is a tag movement. + """ + if oldfnodes == newfnodes: + return [] + oldtags = _tagsfromfnodes(ui, repo, oldfnodes) + newtags = _tagsfromfnodes(ui, repo, newfnodes) + + # list of (tag, old, new): None means missing + entries = [] + for tag, (new, __) in newtags.items(): + new = _nulltonone(new) + old, __ = oldtags.pop(tag, (None, None)) + old = _nulltonone(old) + if old != new: + entries.append((tag, old, new)) + # handle deleted tags + for tag, (old, __) in oldtags.items(): + old = _nulltonone(old) + if old is not None: + entries.append((tag, old, None)) + entries.sort() + return entries + def findglobaltags(ui, repo): '''Find global tags in a repo: return a tagsmap diff -r b36318e6d2ef -r fe9c4d614600 tests/test-tag.t --- a/tests/test-tag.t Tue Mar 28 06:38:09 2017 +0200 +++ b/tests/test-tag.t Tue Mar 28 10:14:55 2017 +0200 @@ -230,7 +230,6 @@ > f = file('.hgtags', 'w'); f.write(last); f.close() > EOF $ hg ci -m'broken manual edit of .hgtags' - hook: tag changes detected $ cat .hgtags; echo acb14030fe0a21b60322c440ad2d20cf7685a376 foobar $ hg tag newline @@ -635,7 +634,6 @@ $ printf '' > .hgtags $ hg commit -m 'delete all tags' created new head - hook: tag changes detected $ hg log -r 'max(t7::)' changeset: 17:ffe462b50880 user: test