Patchwork [Bug,5024] New: Unionrepo fails in some cases with filelog.iscensored

mail settings
Date Dec. 24, 2015, 9:07 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/12351/
State Not Applicable
Headers show

Comments - Dec. 24, 2015, 9:07 p.m.

            Bug ID: 5024
           Summary: Unionrepo fails in some cases with filelog.iscensored
           Product: Mercurial
           Version: 3.6.2
          Hardware: PC
                OS: Mac OS
            Status: UNCONFIRMED
          Severity: feature
          Priority: wish
         Component: Mercurial

Created attachment 1888
script to show stacktrace

I couldn't make a simple test case but I can provide an example that reliably

1) Clone yt:
   hg clone -r d9502d848029

2) Clone mjturk's fork:
   hg clone -r 298252ca425b yt-turk

3) Put the attached script into 'yt' (not 'yt-turk')

4) Run the script:
   HGRCPATH=/dev/null ./

The output:
Traceback (most recent call last):
  File "./", line 18, in <module>
    print fctx2.size()
  File "/Users/sean/projects/hg/mercurial/", line 1071, in size
    return self._filelog.size(self._filerev)
  File "/Users/sean/projects/hg/mercurial/", line 76, in size
    if self.iscensored(rev):
  File "/Users/sean/projects/hg/mercurial/", line 185, in
    return self.revlog2.iscensored(rev)
  File "/Users/sean/projects/hg/mercurial/", line 118, in iscensored
    return self.flags(rev) & revlog.REVIDX_ISCENSORED
  File "/Users/sean/projects/hg/mercurial/", line 403, in flags
    return self.index[rev][0] & 0xFFFF
IndexError: revlog index out of range

The bisected changeset is 22a979d1ae56:

changeset:   29659:22a979d1ae56
user:        Mike Edgar <>
date:        Mon Jan 12 15:29:36 2015 -0500
files:       mercurial/
filelog: use censored revlog flag bit to quickly check if a node is censored


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -83,11 +83,11 @@  class filelog(revlog.revlog):
         samehashes = not super(filelog, self).cmp(node, t)
         if samehashes:
             return False

         # censored files compare against the empty file
-        if self._iscensored(node):
+        if self._iscensored(self.rev(node)):
             return text != ''

         # renaming a file produces a different hash, even if the data
         # remains unchanged. Check if it's the case (slow):
         if self.renamed(node):
@@ -105,12 +105,8 @@  class filelog(revlog.revlog):

     def _file(self, f):
         return filelog(self.opener, f)

-    def _iscensored(self, revornode):
+    def _iscensored(self, rev):
         """Check if a file revision is censored."""
-        try:
-            self.revision(revornode)
-            return False
-        except error.CensoredNodeError:
-            return True
+        return self.flags(rev) & revlog.REVIDX_ISCENSORED