comparison mercurial/exchange.py @ 20955:12f161f08d74

bundle2: allow pulling changegroups using bundle2 This changeset refactors the pull code to use a bundle2 when available. We keep bundle2 disabled by default. The current code is not ready for prime time. Ultimately we'll want to unify the API of `bunde10` and `bundle20` to have less different code. But for now, testing the bundle2 exchange flow is an higher priority.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 01 Apr 2014 23:41:32 -0700
parents dba91f8060eb
children dbf0fa39a5b8
comparison
equal deleted inserted replaced
20954:dba91f8060eb 20955:12f161f08d74
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _ 8 from i18n import _
9 from node import hex, nullid 9 from node import hex, nullid
10 import cStringIO
10 import errno 11 import errno
11 import util, scmutil, changegroup, base85 12 import util, scmutil, changegroup, base85
12 import discovery, phases, obsolete, bookmarks 13 import discovery, phases, obsolete, bookmarks, bundle2
13 14
14 15
15 class pushoperation(object): 16 class pushoperation(object):
16 """A object that represent a single push operation 17 """A object that represent a single push operation
17 18
453 raise util.Abort(msg) 454 raise util.Abort(msg)
454 455
455 lock = pullop.repo.lock() 456 lock = pullop.repo.lock()
456 try: 457 try:
457 _pulldiscovery(pullop) 458 _pulldiscovery(pullop)
459 if pullop.remote.capable('bundle2'):
460 _pullbundle2(pullop)
458 if 'changegroup' in pullop.todosteps: 461 if 'changegroup' in pullop.todosteps:
459 _pullchangeset(pullop) 462 _pullchangeset(pullop)
460 if 'phases' in pullop.todosteps: 463 if 'phases' in pullop.todosteps:
461 _pullphase(pullop) 464 _pullphase(pullop)
462 if 'obsmarkers' in pullop.todosteps: 465 if 'obsmarkers' in pullop.todosteps:
476 tmp = discovery.findcommonincoming(pullop.repo.unfiltered(), 479 tmp = discovery.findcommonincoming(pullop.repo.unfiltered(),
477 pullop.remote, 480 pullop.remote,
478 heads=pullop.heads, 481 heads=pullop.heads,
479 force=pullop.force) 482 force=pullop.force)
480 pullop.common, pullop.fetch, pullop.rheads = tmp 483 pullop.common, pullop.fetch, pullop.rheads = tmp
484
485 def _pullbundle2(pullop):
486 """pull data using bundle2
487
488 For now, the only supported data are changegroup."""
489 kwargs = {'bundlecaps': set(['HG20'])}
490 # pulling changegroup
491 pullop.todosteps.remove('changegroup')
492 if not pullop.fetch:
493 pullop.repo.ui.status(_("no changes found\n"))
494 pullop.cgresult = 0
495 else:
496 kwargs['common'] = pullop.common
497 kwargs['heads'] = pullop.heads or pullop.rheads
498 if pullop.heads is None and list(pullop.common) == [nullid]:
499 pullop.repo.ui.status(_("requesting all changes\n"))
500 if kwargs.keys() == ['format']:
501 return # nothing to pull
502 bundle = pullop.remote.getbundle('pull', **kwargs)
503 try:
504 op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
505 except KeyError, exc:
506 raise util.Abort('missing support for %s' % exc)
507 assert len(op.records['changegroup']) == 1
508 pullop.cgresult = op.records['changegroup'][0]['return']
481 509
482 def _pullchangeset(pullop): 510 def _pullchangeset(pullop):
483 """pull changeset from unbundle into the local repo""" 511 """pull changeset from unbundle into the local repo"""
484 # We delay the open of the transaction as late as possible so we 512 # We delay the open of the transaction as late as possible so we
485 # don't open transaction for nothing or you break future useful 513 # don't open transaction for nothing or you break future useful