def handlechangegroup(op, inpart): """apply a changegroup part on the repo This is a very early implementation that will massive rework before being inflicted to any end-user. """ # Make sure we trigger a transaction creation # # The addchangegroup function will get a transaction object by itself, but # we need to make sure we trigger the creation of a transaction object used # for the whole processing scope. op.gettransaction() unpackerversion = inpart.params.get('version', '01') # We should raise an appropriate exception here unpacker = changegroup.packermap[unpackerversion][1] cg = unpacker(inpart, 'UN') # the source and url passed here are overwritten by the one contained in # the transaction.hookargs argument. So 'bundle2' is a placeholder ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') op.records.add('changegroup', {'return': ret}) if op.reply is not None: # This is definitely not the final form of this # return. But one need to start somewhere. part = op.reply.newpart('b2x:reply:changegroup', mandatory=False) part.addparam('in-reply-to', str(inpart.id), mandatory=False) part.addparam('return', '%i' % ret, mandatory=False) assert not inpart.read()
def _pullchangeset(pullop): """pull changeset from unbundle into the local repo""" # We delay the open of the transaction as late as possible so we # don't open transaction for nothing or you break future useful # rollback call pullop.todosteps.remove('changegroup') if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 return pullop.gettransaction() if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) elif pullop.heads is None and pullop.remote.capable('changegroupsubset'): # issue1320, avoid a race if remote changed after discovery pullop.heads = pullop.rheads if pullop.remote.capable('getbundle'): # TODO: get bundlecaps from remote cg = pullop.remote.getbundle('pull', common=pullop.common, heads=pullop.heads or pullop.rheads) elif pullop.heads is None: cg = pullop.remote.changegroup(pullop.fetch, 'pull') elif not pullop.remote.capable('changegroupsubset'): raise util.Abort(_("partial pull cannot be done because " "other repository doesn't support " "changegroupsubset.")) else: cg = pullop.remote.changegroupsubset(pullop.fetch, pullop.heads, 'pull') pullop.cgresult = changegroup.addchangegroup(pullop.repo, cg, 'pull', pullop.remote.url())
def _pullchangeset(pullop): """pull changeset from unbundle into the local repo""" # We delay the open of the transaction as late as possible so we # don't open transaction for nothing or you break future useful # rollback call if 'changegroup' in pullop.stepsdone: return pullop.stepsdone.add('changegroup') if not pullop.fetch: pullop.repo.ui.status(_("no changes found\n")) pullop.cgresult = 0 return pullop.gettransaction() if pullop.heads is None and list(pullop.common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) elif pullop.heads is None and pullop.remote.capable('changegroupsubset'): # issue1320, avoid a race if remote changed after discovery pullop.heads = pullop.rheads if pullop.remote.capable('getbundle'): # TODO: get bundlecaps from remote cg = pullop.remote.getbundle('pull', common=pullop.common, heads=pullop.heads or pullop.rheads) elif pullop.heads is None: cg = pullop.remote.changegroup(pullop.fetch, 'pull') elif not pullop.remote.capable('changegroupsubset'): raise util.Abort(_("partial pull cannot be done because " "other repository doesn't support " "changegroupsubset.")) else: cg = pullop.remote.changegroupsubset(pullop.fetch, pullop.heads, 'pull') pullop.cgresult = changegroup.addchangegroup(pullop.repo, cg, 'pull', pullop.remote.url())
def do_addchangegroup(self): '''DEPRECATED''' if not self.lock: self.sendresponse("not locked") return self.sendresponse("") cg = changegroup.unbundle10(self.fin, "UN") r = changegroup.addchangegroup(self.repo, cg, 'serve', self._client()) self.lock.release() return str(r)
def do_addchangegroup(self): """DEPRECATED""" if not self.lock: self.sendresponse("not locked") return self.sendresponse("") cg = changegroup.cg1unpacker(self.fin, "UN") r = changegroup.addchangegroup(self.repo, cg, "serve", self._client()) self.lock.release() return str(r)
def handlechangegroup(op, inpart): """apply a changegroup part on the repo This is a very early implementation that will massive rework before being inflicted to any end-user. """ # Make sure we trigger a transaction creation # # The addchangegroup function will get a transaction object by itself, but # we need to make sure we trigger the creation of a transaction object used # for the whole processing scope. op.gettransaction() cg = changegroup.unbundle10(inpart, 'UN') ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') op.records.add('changegroup', {'return': ret}) if op.reply is not None: # This is definitly not the final form of this # return. But one need to start somewhere. part = op.reply.newpart('b2x:reply:changegroup') part.addparam('in-reply-to', str(inpart.id), mandatory=False) part.addparam('return', '%i' % ret, mandatory=False) assert not inpart.read()
def handleremotechangegroup(op, inpart): """apply a bundle10 on the repo, given an url and validation information All the information about the remote bundle to import are given as parameters. The parameters include: - url: the url to the bundle10. - size: the bundle10 file size. It is used to validate what was retrieved by the client matches the server knowledge about the bundle. - digests: a space separated list of the digest types provided as parameters. - digest:<digest-type>: the hexadecimal representation of the digest with that name. Like the size, it is used to validate what was retrieved by the client matches what the server knows about the bundle. When multiple digest types are given, all of them are checked. """ try: raw_url = inpart.params['url'] except KeyError: raise util.Abort(_('remote-changegroup: missing "%s" param') % 'url') parsed_url = util.url(raw_url) if parsed_url.scheme not in capabilities['b2x:remote-changegroup']: raise util.Abort( _('remote-changegroup does not support %s urls') % parsed_url.scheme) try: size = int(inpart.params['size']) except ValueError: raise util.Abort( _('remote-changegroup: invalid value for param "%s"') % 'size') except KeyError: raise util.Abort(_('remote-changegroup: missing "%s" param') % 'size') digests = {} for typ in inpart.params.get('digests', '').split(): param = 'digest:%s' % typ try: value = inpart.params[param] except KeyError: raise util.Abort( _('remote-changegroup: missing "%s" param') % param) digests[typ] = value real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests) # Make sure we trigger a transaction creation # # The addchangegroup function will get a transaction object by itself, but # we need to make sure we trigger the creation of a transaction object used # for the whole processing scope. op.gettransaction() import exchange cg = exchange.readbundle(op.repo.ui, real_part, raw_url) if not isinstance(cg, changegroup.cg1unpacker): raise util.Abort( _('%s: not a bundle version 1.0') % util.hidepassword(raw_url)) ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') op.records.add('changegroup', {'return': ret}) if op.reply is not None: # This is definitly not the final form of this # return. But one need to start somewhere. part = op.reply.newpart('b2x:reply:changegroup') part.addparam('in-reply-to', str(inpart.id), mandatory=False) part.addparam('return', '%i' % ret, mandatory=False) try: real_part.validate() except util.Abort, e: raise util.Abort( _('bundle at %s is corrupted:\n%s') % (util.hidepassword(raw_url), str(e)))
def handleremotechangegroup(op, inpart): """apply a bundle10 on the repo, given an url and validation information All the information about the remote bundle to import are given as parameters. The parameters include: - url: the url to the bundle10. - size: the bundle10 file size. It is used to validate what was retrieved by the client matches the server knowledge about the bundle. - digests: a space separated list of the digest types provided as parameters. - digest:<digest-type>: the hexadecimal representation of the digest with that name. Like the size, it is used to validate what was retrieved by the client matches what the server knows about the bundle. When multiple digest types are given, all of them are checked. """ try: raw_url = inpart.params['url'] except KeyError: raise util.Abort(_('remote-changegroup: missing "%s" param') % 'url') parsed_url = util.url(raw_url) if parsed_url.scheme not in capabilities['b2x:remote-changegroup']: raise util.Abort(_('remote-changegroup does not support %s urls') % parsed_url.scheme) try: size = int(inpart.params['size']) except ValueError: raise util.Abort(_('remote-changegroup: invalid value for param "%s"') % 'size') except KeyError: raise util.Abort(_('remote-changegroup: missing "%s" param') % 'size') digests = {} for typ in inpart.params.get('digests', '').split(): param = 'digest:%s' % typ try: value = inpart.params[param] except KeyError: raise util.Abort(_('remote-changegroup: missing "%s" param') % param) digests[typ] = value real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests) # Make sure we trigger a transaction creation # # The addchangegroup function will get a transaction object by itself, but # we need to make sure we trigger the creation of a transaction object used # for the whole processing scope. op.gettransaction() import exchange cg = exchange.readbundle(op.repo.ui, real_part, raw_url) if not isinstance(cg, changegroup.cg1unpacker): raise util.Abort(_('%s: not a bundle version 1.0') % util.hidepassword(raw_url)) ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') op.records.add('changegroup', {'return': ret}) if op.reply is not None: # This is definitly not the final form of this # return. But one need to start somewhere. part = op.reply.newpart('b2x:reply:changegroup') part.addparam('in-reply-to', str(inpart.id), mandatory=False) part.addparam('return', '%i' % ret, mandatory=False) try: real_part.validate() except util.Abort, e: raise util.Abort(_('bundle at %s is corrupted:\n%s') % (util.hidepassword(raw_url), str(e)))
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: r = changegroup.addchangegroup(repo, cg, source, url) finally: if tr is not None: tr.release() lock.release() return r
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: r = changegroup.addchangegroup(repo, cg, source, url) finally: if tr is not None: tr.release() lock.release() return r