comparison mercurial/exchange.py @ 21662:09f19e09f1b4

push: use bundle2 to push phases when available We now use a bundle2 container to push all phase updates at the same time. This is a significant step forward, even if further refactoring is needed to unify phase push with the changeset push.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 27 May 2014 16:33:06 -0700
parents 0696ca0a685b
children cd3c79392056
comparison
equal deleted inserted replaced
21661:2f52a16f2bee 21662:09f19e09f1b4
357 ### Apply local phase on remote 357 ### Apply local phase on remote
358 358
359 # Get the list of all revs draft on remote by public here. 359 # Get the list of all revs draft on remote by public here.
360 # XXX Beware that revset break if droots is not strictly 360 # XXX Beware that revset break if droots is not strictly
361 # XXX root we may want to ensure it is but it is costly 361 # XXX root we may want to ensure it is but it is costly
362 outdated = unfi.set('heads((%ln::%ln) and public())', 362 outdated = unfi.set('heads((%ln::%ln) and public())',
363 droots, cheads) 363 droots, cheads)
364 for newremotehead in outdated: 364
365 r = pushop.remote.pushkey('phases', 365 b2caps = bundle2.bundle2caps(pushop.remote)
366 newremotehead.hex(), 366 if 'b2x:pushkey' in b2caps:
367 str(phases.draft), 367 # server supports bundle2, let's do a batched push through it
368 str(phases.public)) 368 #
369 if not r: 369 # This will eventually be unified with the changesets bundle2 push
370 pushop.ui.warn(_('updating %s to public failed!\n') 370 bundler = bundle2.bundle20(pushop.ui, b2caps)
371 % newremotehead) 371 capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
372 bundler.newpart('b2x:replycaps', data=capsblob)
373 part2node = []
374 enc = pushkey.encode
375 for newremotehead in outdated:
376 part = bundler.newpart('b2x:pushkey')
377 part.addparam('namespace', enc('phases'))
378 part.addparam('key', enc(newremotehead.hex()))
379 part.addparam('old', enc(str(phases.draft)))
380 part.addparam('new', enc(str(phases.public)))
381 part2node.append((part.id, newremotehead))
382 stream = util.chunkbuffer(bundler.getchunks())
383 try:
384 reply = pushop.remote.unbundle(stream, ['force'], 'push')
385 op = bundle2.processbundle(pushop.repo, reply)
386 except error.BundleValueError, exc:
387 raise util.Abort('missing support for %s' % exc)
388 for partid, node in part2node:
389 partrep = op.records.getreplies(partid)
390 results = partrep['pushkey']
391 assert len(results) <= 1
392 msg = None
393 if not results:
394 msg = _('server ignored update of %s to public!\n') % node
395 elif not int(results[0]['return']):
396 msg = _('updating %s to public failed!\n') % node
397 if msg is not None:
398 pushop.ui.warn(msg)
399
400 else:
401 # fallback to independant pushkey command
402 for newremotehead in outdated:
403 r = pushop.remote.pushkey('phases',
404 newremotehead.hex(),
405 str(phases.draft),
406 str(phases.public))
407 if not r:
408 pushop.ui.warn(_('updating %s to public failed!\n')
409 % newremotehead)
372 410
373 def _localphasemove(pushop, nodes, phase=phases.public): 411 def _localphasemove(pushop, nodes, phase=phases.public):
374 """move <nodes> to <phase> in the local source repo""" 412 """move <nodes> to <phase> in the local source repo"""
375 if pushop.locallocked: 413 if pushop.locallocked:
376 phases.advanceboundary(pushop.repo, phase, nodes) 414 phases.advanceboundary(pushop.repo, phase, nodes)