diff --git a/hgext3rd/pushrebase.py b/hgext3rd/pushrebase.py --- a/hgext3rd/pushrebase.py +++ b/hgext3rd/pushrebase.py @@ -210,9 +210,15 @@ def getrebaseparts(repo, peer, outgoing, onto, newhead): parts = [] - if (util.safehasattr(repo.manifestlog, 'datastore') and - repo.ui.configbool("treemanifest", "sendtrees")): - parts.append(createtreepackpart(repo, outgoing)) + if util.safehasattr(repo.manifestlog, 'datastore'): + mfnodes = [] + for node in outgoing.missing: + mfnodes.append(('', repo[node].manifestnode())) + + # Only add trees if we already have them + if not repo.manifestlog.datastore.getmissing(mfnodes): + parts.append(createtreepackpart(repo, outgoing)) + parts.append(createrebasepart(repo, peer, outgoing, onto, newhead)) return parts diff --git a/tests/test-treemanifest-peertopeer.t b/tests/test-treemanifest-peertopeer.t --- a/tests/test-treemanifest-peertopeer.t +++ b/tests/test-treemanifest-peertopeer.t @@ -56,18 +56,7 @@ $ hg -R ../client2 strip -q -r tip -Pushing p2p with sendtrees=False does nothing - $ hg push -q ../client2 - $ ls ../client2/.hg/store/packs/manifests || true - * No such file or directory (glob) - - $ hg -R ../client2 strip -q -r tip - Pushing p2p puts the received packs in the local pack store - $ cat >> .hg/hgrc < [treemanifest] - > sendtrees=True - > EOF $ hg push -q ../client2 $ ls ../client2/.hg/store/packs/manifests 15f45e8ca8affec27464278498594f94a3624815.histidx diff --git a/tests/test-treemanifest-server.t b/tests/test-treemanifest-server.t --- a/tests/test-treemanifest-server.t +++ b/tests/test-treemanifest-server.t @@ -88,19 +88,16 @@ > [extensions] > pushrebase=$TESTDIR/../hgext3rd/pushrebase.py > EOF + $ mv .hg/store/packs .hg/store/packs.bak $ hg push --to mybook pushing to ssh://user@dummy/master searching for changes remote: error: pushes must contain tree manifests when the server has pushrebase.forcetreereceive enabled abort: push failed on remote [255] + $ mv .hg/store/packs.bak .hg/store/packs -Test pushing only trees with commit hooks - $ cat >> .hg/hgrc < [treemanifest] - > sendflat=False - > sendtrees=True - > EOF +Test pushing flat and tree $ cat >> $TESTTMP/myhook.sh < set -xe > [[ \$(hg log -r \$HG_NODE -T '{file_adds}') == 'subdir2/z' ]] && exit 1 @@ -121,6 +118,21 @@ remote: prepushrebase.myhook hook exited with status 1 abort: push failed on remote [255] + +Test pushing only trees with commit hooks + $ cat >> .hg/hgrc < [treemanifest] + > sendflat=False + > EOF + $ hg push --to mybook + pushing to ssh://user@dummy/master + searching for changes + remote: +++ hg log -r 15486e46ccf6947fbb0a0209e6ce479e7f87ffae -T '{file_adds}' + remote: ++ [[ subdir2/z == \s\u\b\d\i\r\2\/\z ]] + remote: ++ exit 1 + remote: prepushrebase.myhook hook exited with status 1 + abort: push failed on remote + [255] $ mv ../master/.hg/hgrc.bak ../master/.hg/hgrc Test pushing only trees (no flats) with pushrebase creates trees on the server @@ -132,6 +144,9 @@ $ ls ../master/.hg/store/meta subdir subdir2 +- Verify it doesn't put anything in the pack directory + $ ls_l ../master/.hg/store | grep pack + [1] $ cd ../master Verify flat was updated and tree was updated, even though only tree was sent 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 @@ -94,7 +94,6 @@ $ cat >> .hg/hgrc < [treemanifest] > treeonly=True - > sendtrees=True > sendflat=False > EOF diff --git a/treemanifest/__init__.py b/treemanifest/__init__.py --- a/treemanifest/__init__.py +++ b/treemanifest/__init__.py @@ -48,12 +48,6 @@ [treemanifest] pullprefetchrevs = master + stable -Setting `treemanifest.sendtrees` to True will include tree packs in sent -bundles. - - [treemanifest] - sendtrees = False - Setting `treemanifest.repackstartrev` and `treemanifest.repackendrev` causes `hg repack --incremental` to only repack the revlog entries in the given range. The default values are 0 and len(changelog) - 1, respectively. @@ -123,7 +117,6 @@ configtable = {} configitem = registrar.configitem(configtable) -configitem('treemanifest', 'sendtrees', default=False) configitem('treemanifest', 'server', default=False) PACK_CATEGORY='manifests' @@ -167,7 +160,7 @@ def getrepocaps(orig, repo, *args, **kwargs): caps = orig(repo, *args, **kwargs) - if repo.ui.configbool('treemanifest', 'sendtrees'): + if treeenabled(repo.ui): caps['treemanifest'] = ('True',) return caps @@ -1055,6 +1048,11 @@ raise error.Abort(_("invalid treegroup pack category: %s") % category) + # Treemanifest servers don't accept tree directly. They must go through + # pushrebase, which uses it's own part type and handler. + if op.repo.svfs.treemanifestserver: + return + if part.params.get('cache', 'False') == 'True': packpath = shallowutil.getcachepackpath(repo, PACK_CATEGORY) else: @@ -1080,15 +1078,15 @@ @exchange.b2partsgenerator(TREEGROUP_PARTTYPE2) def gettreepackpart2(pushop, bundler): """add parts containing trees being pushed""" - if ('treepack' in pushop.stepsdone or - not treeenabled(pushop.repo.ui) or - not pushop.repo.ui.configbool('treemanifest', 'sendtrees')): + if 'treepack' in pushop.stepsdone or not treeenabled(pushop.repo.ui): return pushop.stepsdone.add('treepack') - part = createtreepackpart(pushop.repo, pushop.outgoing, - TREEGROUP_PARTTYPE2) - bundler.addpart(part) + # Only add trees if we have them + if _cansendtrees(pushop.repo, pushop.outgoing.missing): + part = createtreepackpart(pushop.repo, pushop.outgoing, + TREEGROUP_PARTTYPE2) + bundler.addpart(part) @exchange.getbundle2partsgenerator(TREEGROUP_PARTTYPE2) def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None, @@ -1102,8 +1100,16 @@ return outgoing = exchange._computeoutgoing(repo, heads, common) - part = createtreepackpart(repo, outgoing, TREEGROUP_PARTTYPE2) - bundler.addpart(part) + if _cansendtrees(repo, outgoing.missing): + part = createtreepackpart(repo, outgoing, TREEGROUP_PARTTYPE2) + bundler.addpart(part) + +def _cansendtrees(repo, nodes): + mfnodes = [] + for node in nodes: + mfnodes.append(('', repo[node].manifestnode())) + + return not repo.manifestlog.datastore.getmissing(mfnodes) def createtreepackpart(repo, outgoing, partname): rootdir = '' @@ -1485,7 +1491,9 @@ def _addpartsfromopts(orig, ui, repo, bundler, source, outgoing, opts): orig(ui, repo, bundler, source, outgoing, opts) - if ui.configbool('treemanifest', 'sendtrees'): + + # Only add trees if we have them + if _cansendtrees(repo, outgoing.missing): part = createtreepackpart(repo, outgoing, TREEGROUP_PARTTYPE2) bundler.addpart(part)