# HG changeset patch # User Mike Edgar # Date 1423186696 0 # Node ID da14b8eba806b0391ff2597600cc39e1a4c4c3c5 # Parent 9d0b6ef92eb212bf4945822139dac996c4e1322c revlog: special case expanding full-replacement deltas received by exchange When a delta received through exchange is added to a revlog, it will very often be expanded to a full text by applying the delta to its base. If that delta is of a particular form, we can avoid decoding the base revision. This avoids an exception if the base revision is censored. For background and broader design of the censorship feature, see: http://mercurial.selenic.com/wiki/CensorPlan diff -r 9d0b6ef92eb2 -r da14b8eba806 mercurial/revlog.py --- a/mercurial/revlog.py Tue Feb 10 16:17:15 2015 -0800 +++ b/mercurial/revlog.py Fri Feb 06 01:38:16 2015 +0000 @@ -1233,8 +1233,18 @@ if dfh: dfh.flush() ifh.flush() - basetext = self.revision(self.node(cachedelta[0])) - btext[0] = mdiff.patch(basetext, cachedelta[1]) + baserev = cachedelta[0] + delta = cachedelta[1] + # special case deltas which replace entire base; no need to decode + # base revision. this neatly avoids censored bases, which throw when + # they're decoded. + hlen = struct.calcsize(">lll") + if delta[:hlen] == mdiff.replacediffheader(self.rawsize(baserev), + len(delta) - hlen): + btext[0] = delta[hlen:] + else: + basetext = self.revision(self.node(baserev)) + btext[0] = mdiff.patch(basetext, delta) try: self.checkhash(btext[0], p1, p2, node) if flags & REVIDX_ISCENSORED: