# HG changeset patch # User Friedrich Kastner-Masilko # Date 2012-07-11 10:38:42 # Node ID e7167007c08387c904ca656e253d800a3d4a362e # Parent 9937484e863473ece577c0151d46d02d8591aca9 revlog: fix for generaldelta distance calculation The decision whether or not to store a full snapshot instead of a delta is done based on the distance value calculated in _addrevision.builddelta(rev). This calculation traditionally used the fact of deltas only using the previous revision as base. Generaldelta mechanism is changing this, yet the calculation still assumes that current-offset minus chainbase-offset equals chain-length. This appears to be wrong. This patch corrects the calculation by means of using the chainlength function if Generaldelta is used. diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -349,6 +349,15 @@ class revlog(object): rev = base base = index[rev][3] return base + def chainlength(self, rev): + index = self.index + base = index[rev][3] + length = index[rev][1] + while base != rev: + rev = base + base = index[rev][3] + length = length + index[rev][1] + return length def flags(self, rev): return self.index[rev][0] & 0xFFFF def rawsize(self, rev): @@ -1046,10 +1055,11 @@ class revlog(object): chainbase = basecache[1] else: chainbase = self.chainbase(rev) - dist = l + offset - self.start(chainbase) if self._generaldelta: + dist = l + self.chainlength(rev) base = rev else: + dist = l + offset - self.start(chainbase) base = chainbase return dist, l, data, base, chainbase