diff --git a/fastmanifest/implementation.py b/fastmanifest/implementation.py --- a/fastmanifest/implementation.py +++ b/fastmanifest/implementation.py @@ -1016,11 +1016,19 @@ return node def ctxwrite(self, orig, mfctx, transaction, link, p1, p2, added, removed): - node = orig(mfctx, transaction, link, p1, p2, added, removed) - + mfl = mfctx._manifestlog treeenabled = self.ui.configbool("fastmanifest", "usetree") + if (supportsctree and treeenabled and + p1 not in mfl._revlog.nodemap and + not mfl.datastore.getmissing([('', p1)])): + # If p1 is not in the flat manifest but is in the tree store, then + # this is a commit on top of a tree only commit and we should then + # produce a treeonly commit. + node = None + else: + node = orig(mfctx, transaction, link, p1, p2, added, removed) + if supportsctree and treeenabled: - mfl = mfctx._manifestlog datastore = mfl.datastore opener = mfctx._revlog().opener @@ -1082,13 +1090,25 @@ transaction.addabort('treepack', abort) transaction.addpending('treepack', writepending) - dpack = treemanifest.InterceptedMutableDataPack( - transaction.treedatapack, - node, p1) - hpack = treemanifest.InterceptedMutableHistoryPack( - transaction.treehistpack, node, p1) + # If the manifest was already committed as a flat manifest, use + # its node. + if node is not None: + dpack = treemanifest.InterceptedMutableDataPack( + transaction.treedatapack, + node, p1) + hpack = treemanifest.InterceptedMutableHistoryPack( + transaction.treehistpack, node, p1) + else: + dpack = transaction.treedatapack + hpack = transaction.treehistpack + newtreeiter = newtree.finalize(tree) for nname, nnode, ntext, np1text, np1, np2 in newtreeiter: + # If the node wasn't set by a flat manifest, use the tree + # root node. + if node is None and nname == '': + node = nnode + # Not using deltas, since there aren't any other trees in # this pack it could delta against. dpack.add(nname, nnode, revlog.nullid, ntext) diff --git a/tests/test-treemanifest-treeonly.t b/tests/test-treemanifest-treeonly.t --- a/tests/test-treemanifest-treeonly.t +++ b/tests/test-treemanifest-treeonly.t @@ -250,6 +250,28 @@ | ~ +Test turning treeonly off and making sure we can still commit on top of treeonly +commits + $ echo >> subdir/x + $ hg debugindex -m --config treemanifest.treeonly=False | tail -1 + 2 102 51 -1 2 0427baa4e948 85b359fdb09e 000000000000 + $ hg commit -m 'treeonly from hybrid repo' --config treemanifest.treeonly=False + $ hg log -r . -T '{desc}\n' --stat + treeonly from hybrid repo + subdir/x | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + + $ hg log -r . -T '{desc}\n' --stat --config treemanifest.treeonly=False + treeonly from hybrid repo + subdir/x | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + + $ hg debugindex -m --config treemanifest.treeonly=False | tail -1 + 2 102 51 -1 2 0427baa4e948 85b359fdb09e 000000000000 + $ hg strip -r . --config fbamend.safestrip=False + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + saved backup bundle to $TESTTMP/client/.hg/strip-backup/87da9865954c-3cfa5389-backup.hg (glob) + Test peer-to-peer push/pull of tree only commits $ cd .. $ clearcache