Patchwork D10017: tags: return set of invalid nodes from _tagsfromfnodes()

login
register
mail settings
Submitter phabricator
Date Feb. 17, 2021, 7:44 p.m.
Message ID <differential-rev-PHID-DREV-iy5ikdipnzmlvqtu2j5k-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48330/
State New
Headers show

Comments

phabricator - Feb. 17, 2021, 7:44 p.m.
pulkit created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  We pass a list of file nodes to that function but some can be invalid because
  they were read from a cache which was corrupted.
  
  This patches catches LookupError which is being raised because of invalid
  fnodes, builds a set of such nodes and return it to the callers.
  In next patch, we will add logic to update cache in such cases.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10017

AFFECTED FILES
  mercurial/tags.py
  tests/test-tags.t

CHANGE DETAILS




To: pulkit, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

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"
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):