This diff caused a regression - clients may not have a tree manifests entries
for old commits. That causes infinitepush fail with
KeyError: ('', 'f6db63080ed0d9a81adf2cb266646cf5cf73bb79')| ryanmce | |
| durham |
| Restricted Project |
This diff caused a regression - clients may not have a tree manifests entries
for old commits. That causes infinitepush fail with
KeyError: ('', 'f6db63080ed0d9a81adf2cb266646cf5cf73bb79')Run infinitepush with this diff reverted, make sure it doesn't fail
| Lint OK |
| Unit Test Errors |
| Path | Packages | |||
|---|---|---|---|---|
| M | infinitepush/__init__.py (19 lines) | |||
| M | infinitepush/backupcommands.py (12 lines) | |||
| M | infinitepush/bundleparts.py (17 lines) | |||
| M | remotefilelog/shallowbundle.py (2 lines) | |||
| D | M | tests/test-treemanifest-infinitepush.t (107 lines) |
| Commit | Local | Parents | Author | Summary | Date |
|---|---|---|---|---|---|
| 5ec5ba1e34b8 | 6676 | f09e752a274f | Stanislau Hlebik | infinitepush: revert D721 (Show More…) | Oct 3 2017, 8:29 AM |
| import socket | import socket | ||||
| import struct | import struct | ||||
| import subprocess | import subprocess | ||||
| import sys | import sys | ||||
| import tempfile | import tempfile | ||||
| import time | import time | ||||
| from .bundleparts import ( | from .bundleparts import ( | ||||
| getscratchbranchparts, | getscratchbranchpart, | ||||
| scratchbookmarksparttype, | scratchbookmarksparttype, | ||||
| scratchbranchparttype, | scratchbranchparttype, | ||||
| ) | ) | ||||
| from . import ( | from . import ( | ||||
| backupcommands, | backupcommands, | ||||
| infinitepushcommands, | infinitepushcommands, | ||||
| common, | common, | ||||
| ) | ) | ||||
| # This parameter tells the server that the following bundle is an | # This parameter tells the server that the following bundle is an | ||||
| # infinitepush. This let's it switch the part processing to our infinitepush | # infinitepush. This let's it switch the part processing to our infinitepush | ||||
| # code path. | # code path. | ||||
| bundler.addparam("infinitepush", "True") | bundler.addparam("infinitepush", "True") | ||||
| nonforwardmove = pushop.force or pushop.ui.configbool(experimental, | nonforwardmove = pushop.force or pushop.ui.configbool(experimental, | ||||
| confignonforwardmove) | confignonforwardmove) | ||||
| scratchparts = getscratchbranchparts(pushop.repo, | scratchpart = getscratchbranchpart(pushop.repo, | ||||
| pushop.remote, | pushop.remote, | ||||
| pushop.outgoing, | pushop.outgoing, | ||||
| nonforwardmove, | nonforwardmove, | ||||
| pushop.ui, | pushop.ui, | ||||
| bookmark, | bookmark, | ||||
| create) | create) | ||||
| for scratchpart in scratchparts: | |||||
| bundler.addpart(scratchpart) | bundler.addpart(scratchpart) | ||||
| def handlereply(op): | def handlereply(op): | ||||
| # server either succeeds or aborts; no code to read | # server either succeeds or aborts; no code to read | ||||
| pushop.cgresult = 1 | pushop.cgresult = 1 | ||||
| return handlereply | return handlereply | ||||
| bundle2.capabilities[scratchbranchparttype] = () | bundle2.capabilities[scratchbranchparttype] = () | ||||
| import re | import re | ||||
| import socket | import socket | ||||
| import stat | import stat | ||||
| import subprocess | import subprocess | ||||
| import time | import time | ||||
| from .bundleparts import ( | from .bundleparts import ( | ||||
| getscratchbookmarkspart, | getscratchbookmarkspart, | ||||
| getscratchbranchparts, | getscratchbranchpart, | ||||
| ) | ) | ||||
| from mercurial import ( | from mercurial import ( | ||||
| bundle2, | bundle2, | ||||
| changegroup, | changegroup, | ||||
| commands, | commands, | ||||
| discovery, | discovery, | ||||
| dispatch, | dispatch, | ||||
| encoding, | encoding, | ||||
| # See _deltaparent comments for details | # See _deltaparent comments for details | ||||
| wrapfunction(changegroup.cg2packer, 'deltaparent', _deltaparent) | wrapfunction(changegroup.cg2packer, 'deltaparent', _deltaparent) | ||||
| try: | try: | ||||
| bundler = _createbundler(ui, repo, other) | bundler = _createbundler(ui, repo, other) | ||||
| bundler.addparam("infinitepush", "True") | bundler.addparam("infinitepush", "True") | ||||
| backup = False | backup = False | ||||
| if outgoing and outgoing.missing: | if outgoing and outgoing.missing: | ||||
| backup = True | backup = True | ||||
| parts = getscratchbranchparts(repo, other, outgoing, | bundler.addpart(getscratchbranchpart(repo, other, outgoing, | ||||
| confignonforwardmove=False, | confignonforwardmove=False, | ||||
| ui=ui, bookmark=None, | ui=ui, bookmark=None, | ||||
| create=False) | create=False)) | ||||
| for part in parts: | |||||
| bundler.addpart(part) | |||||
| if bookmarkstobackup: | if bookmarkstobackup: | ||||
| backup = True | backup = True | ||||
| bundler.addpart(getscratchbookmarkspart(other, bookmarkstobackup)) | bundler.addpart(getscratchbookmarkspart(other, bookmarkstobackup)) | ||||
| if backup: | if backup: | ||||
| _sendbundle(bundler, other) | _sendbundle(bundler, other) | ||||
| _writelocalbackupstate(repo.vfs, afterbackupheads, | _writelocalbackupstate(repo.vfs, afterbackupheads, | ||||
| extensions, | extensions, | ||||
| revsetlang, | revsetlang, | ||||
| ) | ) | ||||
| from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
| scratchbranchparttype = 'b2x:infinitepush' | scratchbranchparttype = 'b2x:infinitepush' | ||||
| scratchbookmarksparttype = 'b2x:infinitepushscratchbookmarks' | scratchbookmarksparttype = 'b2x:infinitepushscratchbookmarks' | ||||
| def getscratchbranchparts(repo, peer, outgoing, confignonforwardmove, | def getscratchbranchpart(repo, peer, outgoing, confignonforwardmove, | ||||
| ui, bookmark, create): | ui, bookmark, create): | ||||
| if not outgoing.missing: | if not outgoing.missing: | ||||
| raise error.Abort(_('no commits to push')) | raise error.Abort(_('no commits to push')) | ||||
| if scratchbranchparttype not in bundle2.bundle2caps(peer): | if scratchbranchparttype not in bundle2.bundle2caps(peer): | ||||
| raise error.Abort(_('no server support for %r') % scratchbranchparttype) | raise error.Abort(_('no server support for %r') % scratchbranchparttype) | ||||
| _validaterevset(repo, revsetlang.formatspec('%ln', outgoing.missing), | _validaterevset(repo, revsetlang.formatspec('%ln', outgoing.missing), | ||||
| if confignonforwardmove: | if confignonforwardmove: | ||||
| params['force'] = '1' | params['force'] = '1' | ||||
| # Do not send pushback bundle2 part with bookmarks if remotenames extension | # Do not send pushback bundle2 part with bookmarks if remotenames extension | ||||
| # is enabled. It will be handled manually in `_push()` | # is enabled. It will be handled manually in `_push()` | ||||
| if not isremotebooksenabled(ui): | if not isremotebooksenabled(ui): | ||||
| params['pushbackbookmarks'] = '1' | params['pushbackbookmarks'] = '1' | ||||
| parts = [] | |||||
| # .upper() marks this as a mandatory part: server will abort if there's no | # .upper() marks this as a mandatory part: server will abort if there's no | ||||
| # handler | # handler | ||||
| parts.append(bundle2.bundlepart( | return bundle2.bundlepart( | ||||
| scratchbranchparttype.upper(), | scratchbranchparttype.upper(), | ||||
| advisoryparams=params.iteritems(), | advisoryparams=params.iteritems(), | ||||
| data=cg)) | data=cg) | ||||
| try: | |||||
| treemod = extensions.find('treemanifest') | |||||
| parts.append(treemod.createtreepackpart(repo, outgoing, | |||||
| treemod.TREEGROUP_PARTTYPE2)) | |||||
| except KeyError: | |||||
| pass | |||||
| return parts | |||||
| def getscratchbookmarkspart(peer, bookmarks): | def getscratchbookmarkspart(peer, bookmarks): | ||||
| if scratchbookmarksparttype not in bundle2.bundle2caps(peer): | if scratchbookmarksparttype not in bundle2.bundle2caps(peer): | ||||
| raise error.Abort( | raise error.Abort( | ||||
| _('no server support for %r') % scratchbookmarksparttype) | _('no server support for %r') % scratchbookmarksparttype) | ||||
| return bundle2.bundlepart( | return bundle2.bundlepart( | ||||
| scratchbookmarksparttype.upper(), | scratchbookmarksparttype.upper(), | ||||
| If fastpathlinkrev is false, we are responsible for populating | If fastpathlinkrev is false, we are responsible for populating | ||||
| fnodes. | fnodes. | ||||
| - `args` and `kwargs` are extra arguments that will be passed to the | - `args` and `kwargs` are extra arguments that will be passed to the | ||||
| core generatemanifests method, whose length depends on the | core generatemanifests method, whose length depends on the | ||||
| version of core Hg. | version of core Hg. | ||||
| """ | """ | ||||
| sendflat = self._repo.ui.configbool('treemanifest', 'sendflat', | sendflat = self._repo.ui.configbool('treemanifest', 'sendflat', | ||||
| True) | True) | ||||
| sendflat &= not self._repo.ui.configbool('treemanifest', 'treeonly') | |||||
| if sendflat: | if sendflat: | ||||
| # In this code path, generating the manifests populates fnodes for | # In this code path, generating the manifests populates fnodes for | ||||
| # us. | # us. | ||||
| chunks = super(shallowcg1packer, self).generatemanifests( | chunks = super(shallowcg1packer, self).generatemanifests( | ||||
| commonrevs, | commonrevs, | ||||
| clrevorder, | clrevorder, | ||||
| fastpathlinkrev, | fastpathlinkrev, | ||||
| mfs, | mfs, | ||||
| $ . "$TESTDIR/library.sh" | |||||
| $ . "$TESTDIR/library-infinitepush.sh" | |||||
| $ PYTHONPATH=$TESTDIR/..:$PYTHONPATH | |||||
| $ export PYTHONPATH | |||||
| $ setupcommon | |||||
| $ hginit master | |||||
| $ cd master | |||||
| $ setupserver | |||||
| $ cat >> .hg/hgrc <<EOF | |||||
| > [extensions] | |||||
| > pushrebase=$TESTDIR/../hgext3rd/pushrebase.py | |||||
| > treemanifest=$TESTDIR/../treemanifest | |||||
| > [remotefilelog] | |||||
| > server=True | |||||
| > [treemanifest] | |||||
| > server=True | |||||
| > EOF | |||||
| $ echo x > x | |||||
| $ hg commit -qAm 'add x' | |||||
| $ cd .. | |||||
| Push a scratch branch from one client | |||||
| $ hgcloneshallow ssh://user@dummy/master client1 -q --config extensions.treemanifest=$TESTDIR/../treemanifest --config treemanifest.treeonly=True | |||||
| 1 trees fetched over * (glob) | |||||
| 1 trees fetched over * (glob) | |||||
| 1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over * (glob) | |||||
| $ cd client1 | |||||
| $ cat >> .hg/hgrc <<EOF | |||||
| > [extensions] | |||||
| > treemanifest=$TESTDIR/../treemanifest | |||||
| > | |||||
| > [remotefilelog] | |||||
| > usefastdatapack=True | |||||
| > | |||||
| > [treemanifest] | |||||
| > treeonly=True | |||||
| > EOF | |||||
| $ mkdir subdir | |||||
| $ echo "my change" >> subdir/a | |||||
| $ hg commit -qAm 'add subdir/a' | |||||
| $ hg push --to scratch/foo --create | |||||
| pushing to ssh://user@dummy/master | |||||
| searching for changes | |||||
| remote: pushing 1 commit: | |||||
| remote: 02c12aef64ff add subdir/a | |||||
| $ cd .. | |||||
| Pull a scratch branch from another client | |||||
| $ hgcloneshallow ssh://user@dummy/master client2 -q --config extensions.treemanifest=$TESTDIR/../treemanifest --config treemanifest.treeonly=True | |||||
| $ cd client2 | |||||
| $ cat >> .hg/hgrc <<EOF | |||||
| > [extensions] | |||||
| > treemanifest=$TESTDIR/../treemanifest | |||||
| > | |||||
| > [remotefilelog] | |||||
| > usefastdatapack=True | |||||
| > | |||||
| > [treemanifest] | |||||
| > treeonly=True | |||||
| > EOF | |||||
| $ hg pull -r scratch/foo | |||||
| pulling from ssh://user@dummy/master | |||||
| searching for changes | |||||
| adding changesets | |||||
| adding manifests | |||||
| adding file changes | |||||
| added 1 changesets with 1 changes to 1 files | |||||
| (run 'hg update' to get a working copy) | |||||
| $ hg log -G | |||||
| o changeset: 1:02c12aef64ff | |||||
| | tag: tip | |||||
| | user: test | |||||
| | date: Thu Jan 01 00:00:00 1970 +0000 | |||||
| | summary: add subdir/a | |||||
| | | |||||
| @ changeset: 0:085784c01c08 | |||||
| user: test | |||||
| date: Thu Jan 01 00:00:00 1970 +0000 | |||||
| summary: add x | |||||
| $ hg cat -r tip subdir/a | |||||
| my change | |||||
| $ ls_l .hg/store | |||||
| -rw-r--r-- 257 00changelog.i | |||||
| -rw-r--r-- 108 00manifesttree.i | |||||
| drwxr-xr-x data | |||||
| drwxrwxr-x packs | |||||
| -rw-r--r-- 43 phaseroots | |||||
| -rw-r--r-- 18 undo | |||||
| -rw-r--r-- 17 undo.backupfiles | |||||
| -rw-r--r-- 0 undo.phaseroots | |||||
| $ cd .. | |||||
| Verify its not on the server | |||||
| $ cd master | |||||
| $ hg log -G | |||||
| @ changeset: 0:085784c01c08 | |||||
| tag: tip | |||||
| user: test | |||||
| date: Thu Jan 01 00:00:00 1970 +0000 | |||||
| summary: add x | |||||