comparison mercurial/exchange.py @ 24686:e0e28e910fa3

bundle2: rename format, parts and config to final names It is finally time to freeze the bundle2 format! To do so we: - rename HG2Y to HG20, - drop "b2x:" prefix from all part names, - rename capability to "bundle2-exp" to "bundle2" - rename the hook flag from 'bundle2-exp' to 'bundle2'
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 09 Apr 2015 16:25:48 -0400
parents b83a8f512a80
children 52ff737c63d2
comparison
equal deleted inserted replaced
24685:b3d78d82d84c 24686:e0e28e910fa3
47 remoteversions = bundle2.obsmarkersversion(bundler.capabilities) 47 remoteversions = bundle2.obsmarkersversion(bundler.capabilities)
48 version = obsolete.commonversion(remoteversions) 48 version = obsolete.commonversion(remoteversions)
49 if version is None: 49 if version is None:
50 raise ValueError('bundler do not support common obsmarker format') 50 raise ValueError('bundler do not support common obsmarker format')
51 stream = obsolete.encodemarkers(markers, True, version=version) 51 stream = obsolete.encodemarkers(markers, True, version=version)
52 return bundler.newpart('b2x:obsmarkers', data=stream) 52 return bundler.newpart('obsmarkers', data=stream)
53 return None 53 return None
54 54
55 def _canusebundle2(op): 55 def _canusebundle2(op):
56 """return true if a pull/push can use bundle2 56 """return true if a pull/push can use bundle2
57 57
58 Feel free to nuke this function when we drop the experimental option""" 58 Feel free to nuke this function when we drop the experimental option"""
59 return (op.repo.ui.configbool('experimental', 'bundle2-exp', False) 59 return (op.repo.ui.configbool('experimental', 'bundle2-exp', False)
60 and op.remote.capable('bundle2-exp')) 60 and op.remote.capable('bundle2'))
61 61
62 62
63 class pushoperation(object): 63 class pushoperation(object):
64 """A object that represent a single push operation 64 """A object that represent a single push operation
65 65
457 return 457 return
458 pushop.repo.prepushoutgoinghooks(pushop.repo, 458 pushop.repo.prepushoutgoinghooks(pushop.repo,
459 pushop.remote, 459 pushop.remote,
460 pushop.outgoing) 460 pushop.outgoing)
461 if not pushop.force: 461 if not pushop.force:
462 bundler.newpart('b2x:check:heads', data=iter(pushop.remoteheads)) 462 bundler.newpart('check:heads', data=iter(pushop.remoteheads))
463 b2caps = bundle2.bundle2caps(pushop.remote) 463 b2caps = bundle2.bundle2caps(pushop.remote)
464 version = None 464 version = None
465 cgversions = b2caps.get('b2x:changegroup') 465 cgversions = b2caps.get('changegroup')
466 if not cgversions: # 3.1 and 3.2 ship with an empty value 466 if not cgversions: # 3.1 and 3.2 ship with an empty value
467 cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push', 467 cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
468 pushop.outgoing) 468 pushop.outgoing)
469 else: 469 else:
470 cgversions = [v for v in cgversions if v in changegroup.packermap] 470 cgversions = [v for v in cgversions if v in changegroup.packermap]
472 raise ValueError(_('no common changegroup version')) 472 raise ValueError(_('no common changegroup version'))
473 version = max(cgversions) 473 version = max(cgversions)
474 cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push', 474 cg = changegroup.getlocalchangegroupraw(pushop.repo, 'push',
475 pushop.outgoing, 475 pushop.outgoing,
476 version=version) 476 version=version)
477 cgpart = bundler.newpart('b2x:changegroup', data=cg) 477 cgpart = bundler.newpart('changegroup', data=cg)
478 if version is not None: 478 if version is not None:
479 cgpart.addparam('version', version) 479 cgpart.addparam('version', version)
480 def handlereply(op): 480 def handlereply(op):
481 """extract addchangegroup returns from server reply""" 481 """extract addchangegroup returns from server reply"""
482 cgreplies = op.records.getreplies(cgpart.id) 482 cgreplies = op.records.getreplies(cgpart.id)
488 def _pushb2phases(pushop, bundler): 488 def _pushb2phases(pushop, bundler):
489 """handle phase push through bundle2""" 489 """handle phase push through bundle2"""
490 if 'phases' in pushop.stepsdone: 490 if 'phases' in pushop.stepsdone:
491 return 491 return
492 b2caps = bundle2.bundle2caps(pushop.remote) 492 b2caps = bundle2.bundle2caps(pushop.remote)
493 if not 'b2x:pushkey' in b2caps: 493 if not 'pushkey' in b2caps:
494 return 494 return
495 pushop.stepsdone.add('phases') 495 pushop.stepsdone.add('phases')
496 part2node = [] 496 part2node = []
497 enc = pushkey.encode 497 enc = pushkey.encode
498 for newremotehead in pushop.outdatedphases: 498 for newremotehead in pushop.outdatedphases:
499 part = bundler.newpart('b2x:pushkey') 499 part = bundler.newpart('pushkey')
500 part.addparam('namespace', enc('phases')) 500 part.addparam('namespace', enc('phases'))
501 part.addparam('key', enc(newremotehead.hex())) 501 part.addparam('key', enc(newremotehead.hex()))
502 part.addparam('old', enc(str(phases.draft))) 502 part.addparam('old', enc(str(phases.draft)))
503 part.addparam('new', enc(str(phases.public))) 503 part.addparam('new', enc(str(phases.public)))
504 part2node.append((part.id, newremotehead)) 504 part2node.append((part.id, newremotehead))
531 def _pushb2bookmarks(pushop, bundler): 531 def _pushb2bookmarks(pushop, bundler):
532 """handle phase push through bundle2""" 532 """handle phase push through bundle2"""
533 if 'bookmarks' in pushop.stepsdone: 533 if 'bookmarks' in pushop.stepsdone:
534 return 534 return
535 b2caps = bundle2.bundle2caps(pushop.remote) 535 b2caps = bundle2.bundle2caps(pushop.remote)
536 if 'b2x:pushkey' not in b2caps: 536 if 'pushkey' not in b2caps:
537 return 537 return
538 pushop.stepsdone.add('bookmarks') 538 pushop.stepsdone.add('bookmarks')
539 part2book = [] 539 part2book = []
540 enc = pushkey.encode 540 enc = pushkey.encode
541 for book, old, new in pushop.outbookmarks: 541 for book, old, new in pushop.outbookmarks:
542 part = bundler.newpart('b2x:pushkey') 542 part = bundler.newpart('pushkey')
543 part.addparam('namespace', enc('bookmarks')) 543 part.addparam('namespace', enc('bookmarks'))
544 part.addparam('key', enc(book)) 544 part.addparam('key', enc(book))
545 part.addparam('old', enc(old)) 545 part.addparam('old', enc(old))
546 part.addparam('new', enc(new)) 546 part.addparam('new', enc(new))
547 action = 'update' 547 action = 'update'
581 and pushop.ui.configbool('experimental', 'bundle2.pushback')) 581 and pushop.ui.configbool('experimental', 'bundle2.pushback'))
582 582
583 # create reply capability 583 # create reply capability
584 capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo, 584 capsblob = bundle2.encodecaps(bundle2.getrepocaps(pushop.repo,
585 allowpushback=pushback)) 585 allowpushback=pushback))
586 bundler.newpart('b2x:replycaps', data=capsblob) 586 bundler.newpart('replycaps', data=capsblob)
587 replyhandlers = [] 587 replyhandlers = []
588 for partgenname in b2partsgenorder: 588 for partgenname in b2partsgenorder:
589 partgen = b2partsgenmapping[partgenname] 589 partgen = b2partsgenmapping[partgenname]
590 ret = partgen(pushop, bundler) 590 ret = partgen(pushop, bundler)
591 if callable(ret): 591 if callable(ret):
973 pullop.stepsdone.add('changegroup') 973 pullop.stepsdone.add('changegroup')
974 974
975 kwargs['common'] = pullop.common 975 kwargs['common'] = pullop.common
976 kwargs['heads'] = pullop.heads or pullop.rheads 976 kwargs['heads'] = pullop.heads or pullop.rheads
977 kwargs['cg'] = pullop.fetch 977 kwargs['cg'] = pullop.fetch
978 if 'b2x:listkeys' in remotecaps: 978 if 'listkeys' in remotecaps:
979 kwargs['listkeys'] = ['phase', 'bookmarks'] 979 kwargs['listkeys'] = ['phase', 'bookmarks']
980 if not pullop.fetch: 980 if not pullop.fetch:
981 pullop.repo.ui.status(_("no changes found\n")) 981 pullop.repo.ui.status(_("no changes found\n"))
982 pullop.cgresult = 0 982 pullop.cgresult = 0
983 else: 983 else:
1126 pullop.repo.invalidatevolatilesets() 1126 pullop.repo.invalidatevolatilesets()
1127 return tr 1127 return tr
1128 1128
1129 def caps20to10(repo): 1129 def caps20to10(repo):
1130 """return a set with appropriate options to use bundle20 during getbundle""" 1130 """return a set with appropriate options to use bundle20 during getbundle"""
1131 caps = set(['HG2Y']) 1131 caps = set(['HG20'])
1132 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo)) 1132 capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
1133 caps.add('bundle2=' + urllib.quote(capsblob)) 1133 caps.add('bundle2=' + urllib.quote(capsblob))
1134 return caps 1134 return caps
1135 1135
1136 # List of names of steps to perform for a bundle2 for getbundle, order matters. 1136 # List of names of steps to perform for a bundle2 for getbundle, order matters.
1159 1159
1160 def getbundle(repo, source, heads=None, common=None, bundlecaps=None, 1160 def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
1161 **kwargs): 1161 **kwargs):
1162 """return a full bundle (with potentially multiple kind of parts) 1162 """return a full bundle (with potentially multiple kind of parts)
1163 1163
1164 Could be a bundle HG10 or a bundle HG2Y depending on bundlecaps 1164 Could be a bundle HG10 or a bundle HG20 depending on bundlecaps
1165 passed. For now, the bundle can contain only changegroup, but this will 1165 passed. For now, the bundle can contain only changegroup, but this will
1166 changes when more part type will be available for bundle2. 1166 changes when more part type will be available for bundle2.
1167 1167
1168 This is different from changegroup.getchangegroup that only returns an HG10 1168 This is different from changegroup.getchangegroup that only returns an HG10
1169 changegroup bundle. They may eventually get reunited in the future when we 1169 changegroup bundle. They may eventually get reunited in the future when we
1210 """add a changegroup part to the requested bundle""" 1210 """add a changegroup part to the requested bundle"""
1211 cg = None 1211 cg = None
1212 if kwargs.get('cg', True): 1212 if kwargs.get('cg', True):
1213 # build changegroup bundle here. 1213 # build changegroup bundle here.
1214 version = None 1214 version = None
1215 cgversions = b2caps.get('b2x:changegroup') 1215 cgversions = b2caps.get('changegroup')
1216 if not cgversions: # 3.1 and 3.2 ship with an empty value 1216 if not cgversions: # 3.1 and 3.2 ship with an empty value
1217 cg = changegroup.getchangegroupraw(repo, source, heads=heads, 1217 cg = changegroup.getchangegroupraw(repo, source, heads=heads,
1218 common=common, 1218 common=common,
1219 bundlecaps=bundlecaps) 1219 bundlecaps=bundlecaps)
1220 else: 1220 else:
1226 common=common, 1226 common=common,
1227 bundlecaps=bundlecaps, 1227 bundlecaps=bundlecaps,
1228 version=version) 1228 version=version)
1229 1229
1230 if cg: 1230 if cg:
1231 part = bundler.newpart('b2x:changegroup', data=cg) 1231 part = bundler.newpart('changegroup', data=cg)
1232 if version is not None: 1232 if version is not None:
1233 part.addparam('version', version) 1233 part.addparam('version', version)
1234 1234
1235 @getbundle2partsgenerator('listkeys') 1235 @getbundle2partsgenerator('listkeys')
1236 def _getbundlelistkeysparts(bundler, repo, source, bundlecaps=None, 1236 def _getbundlelistkeysparts(bundler, repo, source, bundlecaps=None,
1237 b2caps=None, **kwargs): 1237 b2caps=None, **kwargs):
1238 """add parts containing listkeys namespaces to the requested bundle""" 1238 """add parts containing listkeys namespaces to the requested bundle"""
1239 listkeys = kwargs.get('listkeys', ()) 1239 listkeys = kwargs.get('listkeys', ())
1240 for namespace in listkeys: 1240 for namespace in listkeys:
1241 part = bundler.newpart('b2x:listkeys') 1241 part = bundler.newpart('listkeys')
1242 part.addparam('namespace', namespace) 1242 part.addparam('namespace', namespace)
1243 keys = repo.listkeys(namespace).items() 1243 keys = repo.listkeys(namespace).items()
1244 part.data = pushkey.encodekeys(keys) 1244 part.data = pushkey.encodekeys(keys)
1245 1245
1246 @getbundle2partsgenerator('obsmarkers') 1246 @getbundle2partsgenerator('obsmarkers')
1286 if util.safehasattr(cg, 'params'): 1286 if util.safehasattr(cg, 'params'):
1287 try: 1287 try:
1288 tr = repo.transaction('unbundle') 1288 tr = repo.transaction('unbundle')
1289 tr.hookargs['source'] = source 1289 tr.hookargs['source'] = source
1290 tr.hookargs['url'] = url 1290 tr.hookargs['url'] = url
1291 tr.hookargs['bundle2-exp'] = '1' 1291 tr.hookargs['bundle2'] = '1'
1292 r = bundle2.processbundle(repo, cg, lambda: tr).reply 1292 r = bundle2.processbundle(repo, cg, lambda: tr).reply
1293 p = lambda: tr.writepending() and repo.root or "" 1293 p = lambda: tr.writepending() and repo.root or ""
1294 repo.hook('b2x-pretransactionclose', throw=True, pending=p, 1294 repo.hook('b2x-pretransactionclose', throw=True, pending=p,
1295 **tr.hookargs) 1295 **tr.hookargs)
1296 hookargs = dict(tr.hookargs) 1296 hookargs = dict(tr.hookargs)