treemanifest: add simple test for tree repack

Summary:
This adds a simple test that verifies hg repack will pack two tree manifest
packs into one.

It caught a bug where creating a treemanifest for a commit with a null parent
produced incorrect output because it constructed an empty tree and tried to use
it's node as the parent of the delta, when there should not have been any delta
in the first place. This is fixed by this diff as well.

Test Plan: Ran the new test

Reviewers: #mercurial, dsyang, rmcelroy

Reviewed By: rmcelroy

Subscribers: rmcelroy, mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D4261591

Signature: t1:4261591:1480705822:ef21fb8cebd8b89f92f58f11bb1dab59bf97664d
This commit is contained in:
Durham Goode 2016-12-02 14:37:55 -08:00
parent 9514bca8ce
commit 51ae957ffc
3 changed files with 80 additions and 4 deletions

View File

@ -1090,16 +1090,21 @@ void writestore(Manifest *mainManifest, const std::vector<char*> &cmpNodes,
static PyObject *treemanifest_write(py_treemanifest *self, PyObject *args,
PyObject *kwargs) {
PyObject* packObj;
py_treemanifest* p1tree = NULL;
PyObject* p1treeObj = NULL;
PyObject* useDeltaObj = NULL;
static char const *kwlist[] = {"pack", "p1tree", "useDeltas", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO", (char**)kwlist,
&packObj, &p1tree, &useDeltaObj)) {
&packObj, &p1treeObj, &useDeltaObj)) {
return NULL;
}
py_treemanifest *p1tree = NULL;
if (p1treeObj && p1treeObj != Py_None) {
p1tree = (py_treemanifest*)p1treeObj;
}
// ParseTuple doesn't increment the ref, but the PythonObj will decrement on
// destruct, so let's increment now.
Py_INCREF(packObj);

View File

@ -0,0 +1,69 @@
$ . "$TESTDIR/library.sh"
$ PYTHONPATH=$TESTDIR/..:$PYTHONPATH
$ export PYTHONPATH
$ cat >> $HGRCPATH <<EOF
> [extensions]
> fastmanifest=
> treemanifest=
>
> [remotefilelog]
> usefastdatapack=True
> reponame=master
>
> [fastmanifest]
> usetree=True
> usecache=False
> EOF
$ hg init master
$ hg clone -q master client
$ cd master
$ echo a > a && hg commit -Aqm 'add a'
$ mkdir dir && echo b > dir/b && hg commit -Aqm 'add dir/b'
$ cd ../client
$ cat >> .hg/hgrc <<EOF
> [treemanifest]
> autocreatetrees=True
> EOF
# Test repacking manifest packs
$ hg pull -q -r 0
$ hg pull -q -r 1
$ ls -l $CACHEDIR/master/packs/manifests | grep datapack
* 100 * 65df85879cdd898607ee3f323a0b61edc7de25b8.datapack (glob)
* 214 * ed42c8e98d598b7c9de7c2660f2a833bb5198b54.datapack (glob)
$ hg debugdatapack $CACHEDIR/master/packs/manifests/65df85879cdd898607ee3f323a0b61edc7de25b8
Node Delta Base Delta Length
a0c8bcbbb45c 000000000000 43
$ hg debugdatapack $CACHEDIR/master/packs/manifests/ed42c8e98d598b7c9de7c2660f2a833bb5198b54
dir/
Node Delta Base Delta Length
23226e7a252c 000000000000 43
Node Delta Base Delta Length
1832e0765de9 a0c8bcbbb45c 58
$ hg repack
$ ls -l $CACHEDIR/master/packs/manifests | grep datapack
* 313 * c217b22cf43133a289290b6ac32d95f2b5a8361e.datapack (glob)
$ hg debugdatapack $CACHEDIR/master/packs/manifests/c217b22cf43133a289290b6ac32d95f2b5a8361e
Node Delta Base Delta Length
1832e0765de9 a0c8bcbbb45c 58
a0c8bcbbb45c 000000000000 43
dir/
Node Delta Base Delta Length
23226e7a252c 000000000000 43

View File

@ -130,7 +130,9 @@ def recordmanifest(pack, repo, oldtip, newtip):
p1 = mfrevlog.parentrevs(rev)[0]
p1node = mfrevlog.node(p1)
if p1node in builttrees:
if p1node == nullid:
origtree = ctreemanifest.treemanifest(repo.svfs.manifestdatastore)
elif p1node in builttrees:
origtree = builttrees[p1node]
else:
origtree = mfl[p1node].read()._treemanifest()
@ -207,7 +209,7 @@ def recordmanifest(pack, repo, oldtip, newtip):
newtree.set(fname, fnode, fflags)
newtree.write(InterceptedMutablePack(pack, mfrevlog.node(rev), p1node),
origtree)
origtree if p1node != nullid else None)
if ui.configbool('treemanifest', 'verifyautocreate', True):
diff = newtree.diff(origtree)