D3151: revlog: move censor logic into main revlog class
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Sat Apr 7 01:23:22 UTC 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG65250a66b55c: revlog: move censor logic into main revlog class (authored by indygreg, committed by ).
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D3151?vs=7765&id=7849
REVISION DETAIL
https://phab.mercurial-scm.org/D3151
AFFECTED FILES
mercurial/filelog.py
mercurial/revlog.py
CHANGE DETAILS
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -117,6 +117,10 @@
metatext = "".join("%s: %s\n" % (k, meta[k]) for k in keys)
return "\1\n%s\1\n%s" % (metatext, text)
+def _censoredtext(text):
+ m, offs = parsemeta(text)
+ return m and "censored" in m
+
def addflagprocessor(flag, processor):
"""Register a flag processor on a revision data flag.
@@ -574,9 +578,11 @@
If mmaplargeindex is True, and an mmapindexthreshold is set, the
index will be mmapped rather than read if it is larger than the
configured threshold.
+
+ If censorable is True, the revlog can have censored revisions.
"""
def __init__(self, opener, indexfile, datafile=None, checkambig=False,
- mmaplargeindex=False):
+ mmaplargeindex=False, censorable=False):
"""
create a revlog object
@@ -589,6 +595,7 @@
# When True, indexfile is opened with checkambig=True at writing, to
# avoid file stat ambiguity.
self._checkambig = checkambig
+ self._censorable = censorable
# 3-tuple of (node, rev, text) for a raw revision.
self._cache = None
# Maps rev to chain base rev.
@@ -1867,14 +1874,19 @@
Available as a function so that subclasses can extend hash mismatch
behaviors as needed.
"""
- if p1 is None and p2 is None:
- p1, p2 = self.parents(node)
- if node != self.hash(text, p1, p2):
- revornode = rev
- if revornode is None:
- revornode = templatefilters.short(hex(node))
- raise RevlogError(_("integrity check failed on %s:%s")
- % (self.indexfile, pycompat.bytestr(revornode)))
+ try:
+ if p1 is None and p2 is None:
+ p1, p2 = self.parents(node)
+ if node != self.hash(text, p1, p2):
+ revornode = rev
+ if revornode is None:
+ revornode = templatefilters.short(hex(node))
+ raise RevlogError(_("integrity check failed on %s:%s")
+ % (self.indexfile, pycompat.bytestr(revornode)))
+ except RevlogError:
+ if self._censorable and _censoredtext(text):
+ raise error.CensoredNodeError(self.indexfile, node, text)
+ raise
def _enforceinlinesize(self, tr, fp=None):
"""Check if the revlog is too big for inline and convert if so.
@@ -2300,11 +2312,33 @@
def iscensored(self, rev):
"""Check if a file revision is censored."""
- return False
+ if not self._censorable:
+ return False
+
+ return self.flags(rev) & REVIDX_ISCENSORED
def _peek_iscensored(self, baserev, delta, flush):
"""Quickly check if a delta produces a censored revision."""
- return False
+ if not self._censorable:
+ return False
+
+ # Fragile heuristic: unless new file meta keys are added alphabetically
+ # preceding "censored", all censored revisions are prefixed by
+ # "\1\ncensored:". A delta producing such a censored revision must be a
+ # full-replacement delta, so we inspect the first and only patch in the
+ # delta for this prefix.
+ hlen = struct.calcsize(">lll")
+ if len(delta) <= hlen:
+ return False
+
+ oldlen = self.rawsize(baserev)
+ newlen = len(delta) - hlen
+ if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
+ return False
+
+ add = "\1\ncensored:"
+ addlen = len(add)
+ return newlen >= addlen and delta[hlen:hlen + addlen] == add
def getstrippoint(self, minlink):
"""find the minimum rev that must be stripped to strip the linkrev
diff --git a/mercurial/filelog.py b/mercurial/filelog.py
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -7,27 +7,20 @@
from __future__ import absolute_import
-import struct
-
from .thirdparty.zope import (
interface as zi,
)
from . import (
- error,
- mdiff,
repository,
revlog,
)
-def _censoredtext(text):
- m, offs = revlog.parsemeta(text)
- return m and "censored" in m
-
@zi.implementer(repository.ifilestorage)
class filelog(revlog.revlog):
def __init__(self, opener, path):
super(filelog, self).__init__(opener,
- "/".join(("data", path + ".i")))
+ "/".join(("data", path + ".i")),
+ censorable=True)
# full name of the user visible file, relative to the repository root
self.filename = path
@@ -90,35 +83,3 @@
return t2 != text
return True
-
- def checkhash(self, text, node, p1=None, p2=None, rev=None):
- try:
- super(filelog, self).checkhash(text, node, p1=p1, p2=p2, rev=rev)
- except error.RevlogError:
- if _censoredtext(text):
- raise error.CensoredNodeError(self.indexfile, node, text)
- raise
-
- def iscensored(self, rev):
- """Check if a file revision is censored."""
- return self.flags(rev) & revlog.REVIDX_ISCENSORED
-
- def _peek_iscensored(self, baserev, delta, flush):
- """Quickly check if a delta produces a censored revision."""
- # Fragile heuristic: unless new file meta keys are added alphabetically
- # preceding "censored", all censored revisions are prefixed by
- # "\1\ncensored:". A delta producing such a censored revision must be a
- # full-replacement delta, so we inspect the first and only patch in the
- # delta for this prefix.
- hlen = struct.calcsize(">lll")
- if len(delta) <= hlen:
- return False
-
- oldlen = self.rawsize(baserev)
- newlen = len(delta) - hlen
- if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
- return False
-
- add = "\1\ncensored:"
- addlen = len(add)
- return newlen >= addlen and delta[hlen:hlen + addlen] == add
To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list