mercurial/filelog.py
changeset 37443 65250a66b55c
parent 37442 0596d27457c6
child 37497 1541e1a8e87d
equal deleted inserted replaced
37442:0596d27457c6 37443:65250a66b55c
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 import struct
       
    11 
       
    12 from .thirdparty.zope import (
    10 from .thirdparty.zope import (
    13     interface as zi,
    11     interface as zi,
    14 )
    12 )
    15 from . import (
    13 from . import (
    16     error,
       
    17     mdiff,
       
    18     repository,
    14     repository,
    19     revlog,
    15     revlog,
    20 )
    16 )
    21 
       
    22 def _censoredtext(text):
       
    23     m, offs = revlog.parsemeta(text)
       
    24     return m and "censored" in m
       
    25 
    17 
    26 @zi.implementer(repository.ifilestorage)
    18 @zi.implementer(repository.ifilestorage)
    27 class filelog(revlog.revlog):
    19 class filelog(revlog.revlog):
    28     def __init__(self, opener, path):
    20     def __init__(self, opener, path):
    29         super(filelog, self).__init__(opener,
    21         super(filelog, self).__init__(opener,
    30                         "/".join(("data", path + ".i")))
    22                         "/".join(("data", path + ".i")),
       
    23                                       censorable=True)
    31         # full name of the user visible file, relative to the repository root
    24         # full name of the user visible file, relative to the repository root
    32         self.filename = path
    25         self.filename = path
    33 
    26 
    34     def read(self, node):
    27     def read(self, node):
    35         t = self.revision(node)
    28         t = self.revision(node)
    88         if self.renamed(node):
    81         if self.renamed(node):
    89             t2 = self.read(node)
    82             t2 = self.read(node)
    90             return t2 != text
    83             return t2 != text
    91 
    84 
    92         return True
    85         return True
    93 
       
    94     def checkhash(self, text, node, p1=None, p2=None, rev=None):
       
    95         try:
       
    96             super(filelog, self).checkhash(text, node, p1=p1, p2=p2, rev=rev)
       
    97         except error.RevlogError:
       
    98             if _censoredtext(text):
       
    99                 raise error.CensoredNodeError(self.indexfile, node, text)
       
   100             raise
       
   101 
       
   102     def iscensored(self, rev):
       
   103         """Check if a file revision is censored."""
       
   104         return self.flags(rev) & revlog.REVIDX_ISCENSORED
       
   105 
       
   106     def _peek_iscensored(self, baserev, delta, flush):
       
   107         """Quickly check if a delta produces a censored revision."""
       
   108         # Fragile heuristic: unless new file meta keys are added alphabetically
       
   109         # preceding "censored", all censored revisions are prefixed by
       
   110         # "\1\ncensored:". A delta producing such a censored revision must be a
       
   111         # full-replacement delta, so we inspect the first and only patch in the
       
   112         # delta for this prefix.
       
   113         hlen = struct.calcsize(">lll")
       
   114         if len(delta) <= hlen:
       
   115             return False
       
   116 
       
   117         oldlen = self.rawsize(baserev)
       
   118         newlen = len(delta) - hlen
       
   119         if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
       
   120             return False
       
   121 
       
   122         add = "\1\ncensored:"
       
   123         addlen = len(add)
       
   124         return newlen >= addlen and delta[hlen:hlen + addlen] == add