generaldelta: initialize basecache properly
Previously basecache was incorrectly initialized before adding the first
revision from a changegroup. Basecache value influences when full revisions are
stored in revlog (when using generaldelta). As a result it was possible to
generate a generaldelta-revlog that could be bigger by arbitrary factor than its
non-generaldelta equivalent.
--- a/mercurial/revlog.py Sat Sep 07 15:07:10 2013 -0500
+++ b/mercurial/revlog.py Fri Sep 20 10:45:51 2013 -0700
@@ -200,7 +200,7 @@
self.datafile = indexfile[:-2] + ".d"
self.opener = opener
self._cache = None
- self._basecache = (0, 0)
+ self._basecache = None
self._chunkcache = (0, '')
self.index = []
self._pcache = {}
@@ -1095,6 +1095,8 @@
offset = self.end(prev)
flags = 0
d = None
+ if self._basecache is None:
+ self._basecache = (prev, self.chainbase(prev))
basecache = self._basecache
p1r, p2r = self.rev(p1), self.rev(p2)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-generaldelta.t Fri Sep 20 10:45:51 2013 -0700
@@ -0,0 +1,23 @@
+Check whether size of generaldelta revlog is not bigger than its
+regular equivalent. Test would fail if generaldelta was naive
+implementation of parentdelta: third manifest revision would be fully
+inserted due to big distance from its paren revision (zero).
+
+ $ hg init repo
+ $ cd repo
+ $ echo foo > foo
+ $ echo bar > bar
+ $ hg commit -q -Am boo
+ $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
+ $ for r in 1 2 3; do
+ > echo $r > foo
+ > hg commit -q -m $r
+ > hg up -q -r 0
+ > hg pull . -q -r $r -R ../gdrepo
+ > done
+ $ cd ..
+ $ regsize=`du -s -b repo/.hg/store/00manifest.i | cut -f 1`
+ $ gdsize=`du -s -b gdrepo/.hg/store/00manifest.i | cut -f 1`
+ $ if ((regsize < gdsize)); then
+ > echo 'generaldelta increased size of a revlog!'
+ > fi