Comments
Patch
@@ -625,8 +625,11 @@
pr()
fl = repo.file(f)
o = len(fl)
- if not fl.addgroup(source, revmap, trp):
- raise util.Abort(_("received file revlog group is empty"))
+ try:
+ if not fl.addgroup(source, revmap, trp):
+ raise util.Abort(_("received file revlog group is empty"))
+ except error.CensoredBaseError, e:
+ raise util.Abort(_("received delta base is censored: %s") % e)
revisions += len(fl) - o
files += 1
if f in needfiles:
@@ -139,3 +139,11 @@
def __init__(self, filename, node):
from node import short
RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
+
+class CensoredBaseError(CensoredNodeError):
+ """error raised when a delta is rejected because its base is censored
+
+ A delta based on a censored revision must be formed as single patch
+ operation which replaces the entire base with new content. This ensures
+ the delta may be applied by clones which have not censored the base.
+ """
@@ -1401,6 +1401,17 @@
_('unknown delta base'))
baserev = self.rev(deltabase)
+
+ if baserev != nullrev and self.iscensored(baserev):
+ # if base is censored, delta must be full replacement in a
+ # single patch operation
+ hlen = struct.calcsize(">lll")
+ oldlen = self.rawsize(baserev)
+ newlen = len(delta) - hlen
+ if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
+ raise error.CensoredBaseError(self.indexfile,
+ self.node(baserev))
+
chain = self._addrevision(node, None, transaction, link,
p1, p2, REVIDX_DEFAULT_FLAGS,
(baserev, delta), ifh, dfh)