diff --git a/mercurial/tags.py b/mercurial/tags.py --- a/mercurial/tags.py +++ b/mercurial/tags.py @@ -117,8 +117,8 @@ """ if oldfnodes == newfnodes: return [] - oldtags = _tagsfromfnodes(ui, repo, oldfnodes) - newtags = _tagsfromfnodes(ui, repo, newfnodes) + oldtags = _tagsfromfnodes(ui, repo, oldfnodes)[0] + newtags = _tagsfromfnodes(ui, repo, newfnodes)[0] # list of (tag, old, new): None means missing entries = [] @@ -200,7 +200,7 @@ head ), b"tag cache returned bogus head %s" % short(head) fnodes = _filterfnodes(tagfnode, reversed(heads)) - alltags = _tagsfromfnodes(ui, repo, fnodes) + alltags, invalidnodes = _tagsfromfnodes(ui, repo, fnodes) # and update the cache (if necessary) if shouldwrite: @@ -225,21 +225,27 @@ def _tagsfromfnodes(ui, repo, fnodes): - """return a tagsmap from a list of file-node + """return a tuple + (tagsmap from a list of file-node, list of invalid fnodes) tagsmap: tag name to (node, hist) 2-tuples. The order of the list matters.""" alltags = {} + invalidfnodes = set() fctx = None for fnode in fnodes: if fctx is None: fctx = repo.filectx(b'.hgtags', fileid=fnode) else: fctx = fctx.filectx(fnode) - filetags = _readtags(ui, repo, fctx.data().splitlines(), fctx) + try: + filetags = _readtags(ui, repo, fctx.data().splitlines(), fctx) + except error.LookupError: + # some fnodes can be invalid because of broken cache + invalidfnodes.add(fnode) _updatetags(filetags, alltags) - return alltags + return (alltags, invalidfnodes) def readlocaltags(ui, repo, alltags, tagtypes): diff --git a/tests/test-tags.t b/tests/test-tags.t --- a/tests/test-tags.t +++ b/tests/test-tags.t @@ -452,8 +452,8 @@ 5 8dbfe60eff306a54259cfe007db9e330e7ecf866 0c04f2a8deadde17fab7422878ee5a2dadbc943d (invalid node) $ hg tags - abort: data/.hgtags.i@0c04f2a8deadde17fab7422878ee5a2dadbc943d: no match found - [50] + tip 5:8dbfe60eff30 + bar 1:78391a272241 BUG: Unless this file is restored, the `hg tags` in the next unix-permissions conditional will fail: "abort: data/.hgtags.i@0c04f2a8dead: no match found"