def _pullbundle2(pullop): """pull data using bundle2 For now, the only supported data are changegroup.""" remotecaps = bundle2.bundle2caps(pullop.remote) kwargs = {'bundlecaps': caps20to10(pullop.repo)} # pulling changegroup pullop.stepsdone.add('changegroup') kwargs['common'] = pullop.common kwargs['heads'] = pullop.heads or pullop.rheads kwargs['cg'] = pullop.fetch if 'b2x:listkeys' in remotecaps: kwargs['listkeys'] = ['phase', 'bookmarks'] if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 else: if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) if obsolete.isenabled(pullop.repo, obsolete.exchangeopt): remoteversions = bundle2.obsmarkersversion(remotecaps) if obsolete.commonversion(remoteversions) is not None: kwargs['obsmarkers'] = True pullop.stepsdone.add('obsmarkers') _pullbundle2extraprepare(pullop, kwargs) if kwargs.keys() == ['format']: return # nothing to pull bundle = pullop.remote.getbundle('pull', **kwargs) try: op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc)
def unbundle(repo, cg, heads, source, url): """Apply a bundle to a repo. this function makes sure the repo is locked during the application and have mechanism to check that no push race occurred between the creation of the bundle and its application. If the push was raced as PushRaced exception is raised.""" r = 0 # need a transaction when processing a bundle2 stream tr = None lock = repo.lock() try: check_heads(repo, heads, 'uploading changes') # push can proceed if util.safehasattr(cg, 'params'): try: tr = repo.transaction('unbundle') tr.hookargs['bundle2-exp'] = '1' r = bundle2.processbundle(repo, cg, lambda: tr).reply cl = repo.unfiltered().changelog p = cl.writepending() and repo.root or "" repo.hook('b2x-pretransactionclose', throw=True, source=source, url=url, pending=p, **tr.hookargs) tr.close() repo.hook('b2x-transactionclose', source=source, url=url, **tr.hookargs) except Exception, exc: exc.duringunbundle2 = True raise else:
def unbundle(repo, cg, heads, source, url): """Apply a bundle to a repo. this function makes sure the repo is locked during the application and have mechanism to check that no push race occurred between the creation of the bundle and its application. If the push was raced as PushRaced exception is raised.""" r = 0 # need a transaction when processing a bundle2 stream tr = None lock = repo.lock() try: check_heads(repo, heads, 'uploading changes') # push can proceed if util.safehasattr(cg, 'params'): try: tr = repo.transaction('unbundle') tr.hookargs['source'] = source tr.hookargs['url'] = url tr.hookargs['bundle2-exp'] = '1' r = bundle2.processbundle(repo, cg, lambda: tr).reply cl = repo.unfiltered().changelog p = cl.writepending() and repo.root or "" repo.hook('b2x-pretransactionclose', throw=True, pending=p, **tr.hookargs) tr.close() hookargs = dict(tr.hookargs) def runhooks(): repo.hook('b2x-transactionclose', **hookargs) repo._afterlock(runhooks) except Exception, exc: exc.duringunbundle2 = True raise else:
def _pullbundle2(pullop): """pull data using bundle2 For now, the only supported data are changegroup.""" remotecaps = bundle2.bundle2caps(pullop.remote) kwargs = {'bundlecaps': caps20to10(pullop.repo)} # pulling changegroup pullop.todosteps.remove('changegroup') kwargs['common'] = pullop.common kwargs['heads'] = pullop.heads or pullop.rheads if 'b2x:listkeys' in remotecaps: kwargs['listkeys'] = ['phase'] if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 else: if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) _pullbundle2extraprepare(pullop, kwargs) if kwargs.keys() == ['format']: return # nothing to pull bundle = pullop.remote.getbundle('pull', **kwargs) try: op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc)
def _pullbundle2(pullop): """pull data using bundle2 For now, the only supported data are changegroup.""" kwargs = {'bundlecaps': set(['HG2X'])} capsblob = bundle2.encodecaps(pullop.repo.bundle2caps) kwargs['bundlecaps'].add('bundle2=' + urllib.quote(capsblob)) # pulling changegroup pullop.todosteps.remove('changegroup') kwargs['common'] = pullop.common kwargs['heads'] = pullop.heads or pullop.rheads if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 else: if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) _pullbundle2extraprepare(pullop, kwargs) if kwargs.keys() == ['format']: return # nothing to pull bundle = pullop.remote.getbundle('pull', **kwargs) try: op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction) except bundle2.UnknownPartError, exc: raise util.Abort('missing support for %s' % exc)
def _pullbundle2(pullop): """pull data using bundle2 For now, the only supported data are changegroup.""" kwargs = {'bundlecaps': set(['HG2X'])} capsblob = bundle2.encodecaps(pullop.repo.bundle2caps) kwargs['bundlecaps'].add('bundle2=' + urllib.quote(capsblob)) # pulling changegroup pullop.todosteps.remove('changegroup') kwargs['common'] = pullop.common kwargs['heads'] = pullop.heads or pullop.rheads if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 else: if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) _pullbundle2extraprepare(pullop, kwargs) if kwargs.keys() == ['format']: return # nothing to pull bundle = pullop.remote.getbundle('pull', **kwargs) try: op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction) except bundle2.UnknownPartError, exc: raise util.Abort('missing support for %s' % exc)
replyhandlers = [] for partgenname in b2partsgenorder: partgen = b2partsgenmapping[partgenname] ret = partgen(pushop, bundler) if callable(ret): replyhandlers.append(ret) # do not push if nothing to push if bundler.nbparts <= 1: return stream = util.chunkbuffer(bundler.getchunks()) try: reply = pushop.remote.unbundle(stream, ['force'], 'push') except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) try: op = bundle2.processbundle(pushop.repo, reply) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) for rephand in replyhandlers: rephand(op) def _pushchangeset(pushop): """Make the actual push of changeset bundle to remote repo""" if 'changesets' in pushop.stepsdone: return pushop.stepsdone.add('changesets') if not _pushcheckoutgoing(pushop): return pushop.repo.prepushoutgoinghooks(pushop.repo, pushop.remote, pushop.outgoing)
ret = partgen(pushop, bundler) if callable(ret): replyhandlers.append(ret) # do not push if nothing to push if bundler.nbparts <= 1: return stream = util.chunkbuffer(bundler.getchunks()) try: reply = pushop.remote.unbundle(stream, ['force'], 'push') except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) try: trgetter = None if pushback: trgetter = pushop.trmanager.transaction op = bundle2.processbundle(pushop.repo, reply, trgetter) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) for rephand in replyhandlers: rephand(op) def _pushchangeset(pushop): """Make the actual push of changeset bundle to remote repo""" if 'changesets' in pushop.stepsdone: return pushop.stepsdone.add('changesets') if not _pushcheckoutgoing(pushop): return pushop.repo.prepushoutgoinghooks(pushop.repo, pushop.remote, pushop.outgoing)
def _pushsyncphase(pushop): """synchronise phase information locally and remotely""" unfi = pushop.repo.unfiltered() cheads = pushop.commonheads # even when we don't push, exchanging phase data is useful remotephases = pushop.remote.listkeys('phases') if (pushop.ui.configbool('ui', '_usedassubrepo', False) and remotephases # server supports phases and pushop.ret is None # nothing was pushed and remotephases.get('publishing', False)): # When: # - this is a subrepo push # - and remote support phase # - and no changeset was pushed # - and remote is publishing # We may be in issue 3871 case! # We drop the possible phase synchronisation done by # courtesy to publish changesets possibly locally draft # on the remote. remotephases = {'publishing': 'True'} if not remotephases: # old server or public only reply from non-publishing _localphasemove(pushop, cheads) # don't push any phase data as there is nothing to push else: ana = phases.analyzeremotephases(pushop.repo, cheads, remotephases) pheads, droots = ana ### Apply remote phase on local if remotephases.get('publishing', False): _localphasemove(pushop, cheads) else: # publish = False _localphasemove(pushop, pheads) _localphasemove(pushop, cheads, phases.draft) ### Apply local phase on remote # Get the list of all revs draft on remote by public here. # XXX Beware that revset break if droots is not strictly # XXX root we may want to ensure it is but it is costly outdated = unfi.set('heads((%ln::%ln) and public())', droots, cheads) b2caps = bundle2.bundle2caps(pushop.remote) if 'b2x:pushkey' in b2caps: # server supports bundle2, let's do a batched push through it # # This will eventually be unified with the changesets bundle2 push bundler = bundle2.bundle20(pushop.ui, b2caps) capsblob = bundle2.encodecaps(pushop.repo.bundle2caps) bundler.newpart('b2x:replycaps', data=capsblob) part2node = [] enc = pushkey.encode for newremotehead in outdated: part = bundler.newpart('b2x:pushkey') part.addparam('namespace', enc('phases')) part.addparam('key', enc(newremotehead.hex())) part.addparam('old', enc(str(phases.draft))) part.addparam('new', enc(str(phases.public))) part2node.append((part.id, newremotehead)) stream = util.chunkbuffer(bundler.getchunks()) try: reply = pushop.remote.unbundle(stream, ['force'], 'push') op = bundle2.processbundle(pushop.repo, reply) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) for partid, node in part2node: partrep = op.records.getreplies(partid) results = partrep['pushkey'] assert len(results) <= 1 msg = None if not results: msg = _('server ignored update of %s to public!\n') % node elif not int(results[0]['return']): msg = _('updating %s to public failed!\n') % node if msg is not None: pushop.ui.warn(msg) else:
bundler.newpart('b2x:replycaps', data=capsblob) replyhandlers = [] for partgen in bundle2partsgenerators: ret = partgen(pushop, bundler) if callable(ret): replyhandlers.append(ret) # do not push if nothing to push if bundler.nbparts <= 1: return stream = util.chunkbuffer(bundler.getchunks()) try: reply = pushop.remote.unbundle(stream, ['force'], 'push') except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) try: op = bundle2.processbundle(pushop.repo, reply) except error.BundleValueError, exc: raise util.Abort('missing support for %s' % exc) for rephand in replyhandlers: rephand(op) def _pushchangeset(pushop): """Make the actual push of changeset bundle to remote repo""" if 'changesets' in pushop.stepsdone: return pushop.stepsdone.add('changesets') if not _pushcheckoutgoing(pushop): return pushop.repo.prepushoutgoinghooks(pushop.repo, pushop.remote, pushop.outgoing)