##// END OF EJS Templates
revlog: move censor logic into main revlog class...
Gregory Szorc -
r37461:65250a66 default
parent child Browse files
Show More
@@ -7,27 +7,20 b''
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
17
22 def _censoredtext(text):
23 m, offs = revlog.parsemeta(text)
24 return m and "censored" in m
25
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
@@ -90,35 +83,3 b' class filelog(revlog.revlog):'
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
@@ -117,6 +117,10 b' def packmeta(meta, text):'
117 metatext = "".join("%s: %s\n" % (k, meta[k]) for k in keys)
117 metatext = "".join("%s: %s\n" % (k, meta[k]) for k in keys)
118 return "\1\n%s\1\n%s" % (metatext, text)
118 return "\1\n%s\1\n%s" % (metatext, text)
119
119
120 def _censoredtext(text):
121 m, offs = parsemeta(text)
122 return m and "censored" in m
123
120 def addflagprocessor(flag, processor):
124 def addflagprocessor(flag, processor):
121 """Register a flag processor on a revision data flag.
125 """Register a flag processor on a revision data flag.
122
126
@@ -574,9 +578,11 b' class revlog(object):'
574 If mmaplargeindex is True, and an mmapindexthreshold is set, the
578 If mmaplargeindex is True, and an mmapindexthreshold is set, the
575 index will be mmapped rather than read if it is larger than the
579 index will be mmapped rather than read if it is larger than the
576 configured threshold.
580 configured threshold.
581
582 If censorable is True, the revlog can have censored revisions.
577 """
583 """
578 def __init__(self, opener, indexfile, datafile=None, checkambig=False,
584 def __init__(self, opener, indexfile, datafile=None, checkambig=False,
579 mmaplargeindex=False):
585 mmaplargeindex=False, censorable=False):
580 """
586 """
581 create a revlog object
587 create a revlog object
582
588
@@ -589,6 +595,7 b' class revlog(object):'
589 # When True, indexfile is opened with checkambig=True at writing, to
595 # When True, indexfile is opened with checkambig=True at writing, to
590 # avoid file stat ambiguity.
596 # avoid file stat ambiguity.
591 self._checkambig = checkambig
597 self._checkambig = checkambig
598 self._censorable = censorable
592 # 3-tuple of (node, rev, text) for a raw revision.
599 # 3-tuple of (node, rev, text) for a raw revision.
593 self._cache = None
600 self._cache = None
594 # Maps rev to chain base rev.
601 # Maps rev to chain base rev.
@@ -1867,14 +1874,19 b' class revlog(object):'
1867 Available as a function so that subclasses can extend hash mismatch
1874 Available as a function so that subclasses can extend hash mismatch
1868 behaviors as needed.
1875 behaviors as needed.
1869 """
1876 """
1870 if p1 is None and p2 is None:
1877 try:
1871 p1, p2 = self.parents(node)
1878 if p1 is None and p2 is None:
1872 if node != self.hash(text, p1, p2):
1879 p1, p2 = self.parents(node)
1873 revornode = rev
1880 if node != self.hash(text, p1, p2):
1874 if revornode is None:
1881 revornode = rev
1875 revornode = templatefilters.short(hex(node))
1882 if revornode is None:
1876 raise RevlogError(_("integrity check failed on %s:%s")
1883 revornode = templatefilters.short(hex(node))
1877 % (self.indexfile, pycompat.bytestr(revornode)))
1884 raise RevlogError(_("integrity check failed on %s:%s")
1885 % (self.indexfile, pycompat.bytestr(revornode)))
1886 except RevlogError:
1887 if self._censorable and _censoredtext(text):
1888 raise error.CensoredNodeError(self.indexfile, node, text)
1889 raise
1878
1890
1879 def _enforceinlinesize(self, tr, fp=None):
1891 def _enforceinlinesize(self, tr, fp=None):
1880 """Check if the revlog is too big for inline and convert if so.
1892 """Check if the revlog is too big for inline and convert if so.
@@ -2300,11 +2312,33 b' class revlog(object):'
2300
2312
2301 def iscensored(self, rev):
2313 def iscensored(self, rev):
2302 """Check if a file revision is censored."""
2314 """Check if a file revision is censored."""
2303 return False
2315 if not self._censorable:
2316 return False
2317
2318 return self.flags(rev) & REVIDX_ISCENSORED
2304
2319
2305 def _peek_iscensored(self, baserev, delta, flush):
2320 def _peek_iscensored(self, baserev, delta, flush):
2306 """Quickly check if a delta produces a censored revision."""
2321 """Quickly check if a delta produces a censored revision."""
2307 return False
2322 if not self._censorable:
2323 return False
2324
2325 # Fragile heuristic: unless new file meta keys are added alphabetically
2326 # preceding "censored", all censored revisions are prefixed by
2327 # "\1\ncensored:". A delta producing such a censored revision must be a
2328 # full-replacement delta, so we inspect the first and only patch in the
2329 # delta for this prefix.
2330 hlen = struct.calcsize(">lll")
2331 if len(delta) <= hlen:
2332 return False
2333
2334 oldlen = self.rawsize(baserev)
2335 newlen = len(delta) - hlen
2336 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
2337 return False
2338
2339 add = "\1\ncensored:"
2340 addlen = len(add)
2341 return newlen >= addlen and delta[hlen:hlen + addlen] == add
2308
2342
2309 def getstrippoint(self, minlink):
2343 def getstrippoint(self, minlink):
2310 """find the minimum rev that must be stripped to strip the linkrev
2344 """find the minimum rev that must be stripped to strip the linkrev
General Comments 0
You need to be logged in to leave comments. Login now