示例#1
0
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    # Send known head to the server for race detection.
    capsblob = urllib.unquote(pushop.remote.capable('bundle2-exp'))
    caps = bundle2.decodecaps(capsblob)
    bundler = bundle2.bundle20(pushop.ui, caps)
    # create reply capability
    capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
    bundler.addpart(bundle2.bundlepart('b2x:replycaps', data=capsblob))
    if not pushop.force:
        part = bundle2.bundlepart('B2X:CHECK:HEADS',
                                  data=iter(pushop.remoteheads))
        bundler.addpart(part)
    extrainfo = _pushbundle2extraparts(pushop, bundler)
    # add the changegroup bundle
    cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
    cgpart = bundle2.bundlepart('B2X:CHANGEGROUP', data=cg.getchunks())
    bundler.addpart(cgpart)
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
示例#2
0
def _pushbundle2(pushop):
    """push data to the remote using bundle2

    The only currently supported type of data is changegroup but this will
    evolve in the future."""
    # Send known head to the server for race detection.
    capsblob = urllib.unquote(pushop.remote.capable('bundle2-exp'))
    caps = bundle2.decodecaps(capsblob)
    bundler = bundle2.bundle20(pushop.ui, caps)
    # create reply capability
    capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
    bundler.addpart(bundle2.bundlepart('b2x:replycaps', data=capsblob))
    if not pushop.force:
        part = bundle2.bundlepart('B2X:CHECK:HEADS',
                                  data=iter(pushop.remoteheads))
        bundler.addpart(part)
    extrainfo = _pushbundle2extraparts(pushop, bundler)
    # add the changegroup bundle
    cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
    cgpart = bundle2.bundlepart('B2X:CHANGEGROUP', data=cg.getchunks())
    bundler.addpart(cgpart)
    stream = util.chunkbuffer(bundler.getchunks())
    try:
        reply = pushop.remote.unbundle(stream, ['force'], 'push')
    except bundle2.UnknownPartError, exc:
        raise util.Abort('missing support for %s' % exc)
示例#3
0
def unbundle(repo, proto, heads):
    their_heads = decodelist(heads)

    try:
        proto.redirect()

        exchange.check_heads(repo, their_heads, 'preparing changes')

        # write bundle data to temporary file because it can be big
        fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
        fp = os.fdopen(fd, 'wb+')
        r = 0
        try:
            proto.getfile(fp)
            fp.seek(0)
            gen = exchange.readbundle(repo.ui, fp, None)
            r = exchange.unbundle(repo, gen, their_heads, 'serve',
                                  proto._client())
            if util.safehasattr(r, 'addpart'):
                # The return looks streameable, we are in the bundle2 case and
                # should return a stream.
                return streamres(r.getchunks())
            return pushres(r)

        finally:
            fp.close()
            os.unlink(tempname)
    except bundle2.UnknownPartError, exc:
            bundler = bundle2.bundle20(repo.ui)
            part = bundle2.bundlepart('B2X:ERROR:UNKNOWNPART',
                                      [('parttype', str(exc))])
            bundler.addpart(part)
            return streamres(bundler.getchunks())
示例#4
0
def unbundle(repo, proto, heads):
    their_heads = decodelist(heads)

    try:
        proto.redirect()

        exchange.check_heads(repo, their_heads, 'preparing changes')

        # write bundle data to temporary file because it can be big
        fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
        fp = os.fdopen(fd, 'wb+')
        r = 0
        try:
            proto.getfile(fp)
            fp.seek(0)
            gen = exchange.readbundle(repo.ui, fp, None)
            r = exchange.unbundle(repo, gen, their_heads, 'serve',
                                  proto._client())
            if util.safehasattr(r, 'addpart'):
                # The return looks streameable, we are in the bundle2 case and
                # should return a stream.
                return streamres(r.getchunks())
            return pushres(r)

        finally:
            fp.close()
            os.unlink(tempname)
    except bundle2.UnknownPartError, exc:
        bundler = bundle2.bundle20(repo.ui)
        part = bundle2.bundlepart('B2X:ERROR:UNKNOWNPART',
                                  [('parttype', str(exc))])
        bundler.addpart(part)
        return streamres(bundler.getchunks())
示例#5
0
def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
              **kwargs):
    """return a full bundle (with potentially multiple kind of parts)

    Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
    passed. For now, the bundle can contain only changegroup, but this will
    changes when more part type will be available for bundle2.

    This is different from changegroup.getbundle that only returns an HG10
    changegroup bundle. They may eventually get reunited in the future when we
    have a clearer idea of the API we what to query different data.

    The implementation is at a very early stage and will get massive rework
    when the API of bundle is refined.
    """
    # build changegroup bundle here.
    cg = changegroup.getbundle(repo, source, heads=heads,
                               common=common, bundlecaps=bundlecaps)
    if bundlecaps is None or 'HG2X' not in bundlecaps:
        return cg
    # very crude first implementation,
    # the bundle API will change and the generation will be done lazily.
    b2caps = {}
    for bcaps in bundlecaps:
        if bcaps.startswith('bundle2='):
            blob = urllib.unquote(bcaps[len('bundle2='):])
            b2caps.update(bundle2.decodecaps(blob))
    bundler = bundle2.bundle20(repo.ui, b2caps)
    if cg:
        part = bundle2.bundlepart('b2x:changegroup', data=cg.getchunks())
        bundler.addpart(part)
    _getbundleextrapart(bundler, repo, source, heads=heads, common=common,
                        bundlecaps=bundlecaps, **kwargs)
    return util.chunkbuffer(bundler.getchunks())
示例#6
0
def getbundle(repo,
              source,
              heads=None,
              common=None,
              bundlecaps=None,
              **kwargs):
    """return a full bundle (with potentially multiple kind of parts)

    Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
    passed. For now, the bundle can contain only changegroup, but this will
    changes when more part type will be available for bundle2.

    This is different from changegroup.getbundle that only returns an HG10
    changegroup bundle. They may eventually get reunited in the future when we
    have a clearer idea of the API we what to query different data.

    The implementation is at a very early stage and will get massive rework
    when the API of bundle is refined.
    """
    # build changegroup bundle here.
    cg = changegroup.getbundle(repo,
                               source,
                               heads=heads,
                               common=common,
                               bundlecaps=bundlecaps)
    if bundlecaps is None or 'HG2X' not in bundlecaps:
        return cg
    # very crude first implementation,
    # the bundle API will change and the generation will be done lazily.
    b2caps = {}
    for bcaps in bundlecaps:
        if bcaps.startswith('bundle2='):
            blob = urllib.unquote(bcaps[len('bundle2='):])
            b2caps.update(bundle2.decodecaps(blob))
    bundler = bundle2.bundle20(repo.ui, b2caps)
    if cg:
        part = bundle2.bundlepart('b2x:changegroup', data=cg.getchunks())
        bundler.addpart(part)
    _getbundleextrapart(bundler,
                        repo,
                        source,
                        heads=heads,
                        common=common,
                        bundlecaps=bundlecaps,
                        **kwargs)
    return util.chunkbuffer(bundler.getchunks())
示例#7
0
            errpart = bundler.newpart('b2x:error:unsupportedcontent')
            if exc.parttype is not None:
                errpart.addparam('parttype', exc.parttype)
            if exc.params:
                errpart.addparam('params', '\0'.join(exc.params))
            return streamres(bundler.getchunks())
    except util.Abort, inst:
        # The old code we moved used sys.stderr directly.
        # We did not change it to minimise code change.
        # This need to be moved to something proper.
        # Feel free to do it.
        if getattr(inst, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            manargs = [('message', str(inst))]
            advargs = []
            if inst.hint is not None:
                advargs.append(('hint', inst.hint))
            bundler.addpart(bundle2.bundlepart('b2x:error:abort',
                                               manargs, advargs))
            return streamres(bundler.getchunks())
        else:
            sys.stderr.write("abort: %s\n" % inst)
            return pushres(0)
    except error.PushRaced, exc:
        if getattr(exc, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            bundler.newpart('b2x:error:pushraced', [('message', str(exc))])
            return streamres(bundler.getchunks())
        else:
            return pusherr(str(exc))
示例#8
0
def unbundle(repo, proto, heads):
    their_heads = decodelist(heads)

    try:
        proto.redirect()

        exchange.check_heads(repo, their_heads, 'preparing changes')

        # write bundle data to temporary file because it can be big
        fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
        fp = os.fdopen(fd, 'wb+')
        r = 0
        try:
            proto.getfile(fp)
            fp.seek(0)
            gen = exchange.readbundle(repo.ui, fp, None)
            r = exchange.unbundle(repo, gen, their_heads, 'serve',
                                  proto._client())
            if util.safehasattr(r, 'addpart'):
                # The return looks streamable, we are in the bundle2 case and
                # should return a stream.
                return streamres(r.getchunks())
            return pushres(r)

        finally:
            fp.close()
            os.unlink(tempname)

    except (error.BundleValueError, util.Abort, error.PushRaced) as exc:
        # handle non-bundle2 case first
        if not getattr(exc, 'duringunbundle2', False):
            try:
                raise
            except util.Abort:
                # The old code we moved used sys.stderr directly.
                # We did not change it to minimise code change.
                # This need to be moved to something proper.
                # Feel free to do it.
                sys.stderr.write("abort: %s\n" % exc)
                return pushres(0)
            except error.PushRaced:
                return pusherr(str(exc))

        bundler = bundle2.bundle20(repo.ui)
        for out in getattr(exc, '_bundle2salvagedoutput', ()):
            bundler.addpart(out)
        try:
            try:
                raise
            except error.PushkeyFailed as exc:
                # check client caps
                remotecaps = getattr(exc, '_replycaps', None)
                if (remotecaps is not None
                        and 'pushkey' not in remotecaps.get('error', ())):
                    # no support remote side, fallback to Abort handler.
                    raise
                part = bundler.newpart('error:pushkey')
                part.addparam('in-reply-to', exc.partid)
                if exc.namespace is not None:
                    part.addparam('namespace', exc.namespace, mandatory=False)
                if exc.key is not None:
                    part.addparam('key', exc.key, mandatory=False)
                if exc.new is not None:
                    part.addparam('new', exc.new, mandatory=False)
                if exc.old is not None:
                    part.addparam('old', exc.old, mandatory=False)
                if exc.ret is not None:
                    part.addparam('ret', exc.ret, mandatory=False)
        except error.BundleValueError as exc:
            errpart = bundler.newpart('error:unsupportedcontent')
            if exc.parttype is not None:
                errpart.addparam('parttype', exc.parttype)
            if exc.params:
                errpart.addparam('params', '\0'.join(exc.params))
        except util.Abort as exc:
            manargs = [('message', str(exc))]
            advargs = []
            if exc.hint is not None:
                advargs.append(('hint', exc.hint))
            bundler.addpart(bundle2.bundlepart('error:abort', manargs,
                                               advargs))
        except error.PushRaced as exc:
            bundler.newpart('error:pushraced', [('message', str(exc))])
        return streamres(bundler.getchunks())
示例#9
0
        errpart = bundler.newpart('B2X:ERROR:UNSUPPORTEDCONTENT')
        if exc.parttype is not None:
            errpart.addparam('parttype', exc.parttype)
        if exc.params:
            errpart.addparam('params', '\0'.join(exc.params))
        return streamres(bundler.getchunks())
    except util.Abort, inst:
        # The old code we moved used sys.stderr directly.
        # We did not change it to minimise code change.
        # This need to be moved to something proper.
        # Feel free to do it.
        if getattr(inst, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            manargs = [('message', str(inst))]
            advargs = []
            if inst.hint is not None:
                advargs.append(('hint', inst.hint))
            bundler.addpart(
                bundle2.bundlepart('B2X:ERROR:ABORT', manargs, advargs))
            return streamres(bundler.getchunks())
        else:
            sys.stderr.write("abort: %s\n" % inst)
            return pushres(0)
    except error.PushRaced, exc:
        if getattr(exc, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            bundler.newpart('B2X:ERROR:PUSHRACED', [('message', str(exc))])
            return streamres(bundler.getchunks())
        else:
            return pusherr(str(exc))
示例#10
0
            errpart = bundler.newpart('B2X:ERROR:UNSUPPORTEDCONTENT')
            if exc.parttype is not None:
                errpart.addparam('parttype', exc.parttype)
            if exc.params:
                errpart.addparam('params', '\0'.join(exc.params))
            return streamres(bundler.getchunks())
    except util.Abort, inst:
        # The old code we moved used sys.stderr directly.
        # We did not change it to minimise code change.
        # This need to be moved to something proper.
        # Feel free to do it.
        if getattr(inst, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            manargs = [('message', str(inst))]
            advargs = []
            if inst.hint is not None:
                advargs.append(('hint', inst.hint))
            bundler.addpart(bundle2.bundlepart('B2X:ERROR:ABORT',
                                               manargs, advargs))
            return streamres(bundler.getchunks())
        else:
            sys.stderr.write("abort: %s\n" % inst)
            return pushres(0)
    except error.PushRaced, exc:
        if getattr(exc, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            bundler.newpart('B2X:ERROR:PUSHRACED', [('message', str(exc))])
            return streamres(bundler.getchunks())
        else:
            return pusherr(str(exc))
示例#11
0
            part = bundle2.bundlepart('B2X:ERROR:UNKNOWNPART',
                                      [('parttype', str(exc))])
            bundler.addpart(part)
            return streamres(bundler.getchunks())
    except util.Abort, inst:
        # The old code we moved used sys.stderr directly.
        # We did not change it to minimise code change.
        # This need to be moved to something proper.
        # Feel free to do it.
        if getattr(inst, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            manargs = [('message', str(inst))]
            advargs = []
            if inst.hint is not None:
                advargs.append(('hint', inst.hint))
            bundler.addpart(bundle2.bundlepart('B2X:ERROR:ABORT',
                                               manargs, advargs))
            return streamres(bundler.getchunks())
        else:
            sys.stderr.write("abort: %s\n" % inst)
            return pushres(0)
    except error.PushRaced, exc:
        if getattr(exc, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            part = bundle2.bundlepart('B2X:ERROR:PUSHRACED',
                                      [('message', str(exc))])
            bundler.addpart(part)
            return streamres(bundler.getchunks())
        else:
            return pusherr(str(exc))
示例#12
0
def unbundle(repo, proto, heads):
    their_heads = decodelist(heads)

    try:
        proto.redirect()

        exchange.check_heads(repo, their_heads, "preparing changes")

        # write bundle data to temporary file because it can be big
        fd, tempname = tempfile.mkstemp(prefix="hg-unbundle-")
        fp = os.fdopen(fd, "wb+")
        r = 0
        try:
            proto.getfile(fp)
            fp.seek(0)
            gen = exchange.readbundle(repo.ui, fp, None)
            r = exchange.unbundle(repo, gen, their_heads, "serve", proto._client())
            if util.safehasattr(r, "addpart"):
                # The return looks streamable, we are in the bundle2 case and
                # should return a stream.
                return streamres(r.getchunks())
            return pushres(r)

        finally:
            fp.close()
            os.unlink(tempname)

    except (error.BundleValueError, util.Abort, error.PushRaced) as exc:
        # handle non-bundle2 case first
        if not getattr(exc, "duringunbundle2", False):
            try:
                raise
            except util.Abort:
                # The old code we moved used sys.stderr directly.
                # We did not change it to minimise code change.
                # This need to be moved to something proper.
                # Feel free to do it.
                sys.stderr.write("abort: %s\n" % exc)
                return pushres(0)
            except error.PushRaced:
                return pusherr(str(exc))

        bundler = bundle2.bundle20(repo.ui)
        for out in getattr(exc, "_bundle2salvagedoutput", ()):
            bundler.addpart(out)
        try:
            try:
                raise
            except error.PushkeyFailed as exc:
                # check client caps
                remotecaps = getattr(exc, "_replycaps", None)
                if remotecaps is not None and "pushkey" not in remotecaps.get("error", ()):
                    # no support remote side, fallback to Abort handler.
                    raise
                part = bundler.newpart("error:pushkey")
                part.addparam("in-reply-to", exc.partid)
                if exc.namespace is not None:
                    part.addparam("namespace", exc.namespace, mandatory=False)
                if exc.key is not None:
                    part.addparam("key", exc.key, mandatory=False)
                if exc.new is not None:
                    part.addparam("new", exc.new, mandatory=False)
                if exc.old is not None:
                    part.addparam("old", exc.old, mandatory=False)
                if exc.ret is not None:
                    part.addparam("ret", exc.ret, mandatory=False)
        except error.BundleValueError as exc:
            errpart = bundler.newpart("error:unsupportedcontent")
            if exc.parttype is not None:
                errpart.addparam("parttype", exc.parttype)
            if exc.params:
                errpart.addparam("params", "\0".join(exc.params))
        except util.Abort as exc:
            manargs = [("message", str(exc))]
            advargs = []
            if exc.hint is not None:
                advargs.append(("hint", exc.hint))
            bundler.addpart(bundle2.bundlepart("error:abort", manargs, advargs))
        except error.PushRaced as exc:
            bundler.newpart("error:pushraced", [("message", str(exc))])
        return streamres(bundler.getchunks())
示例#13
0
        part = bundle2.bundlepart('B2X:ERROR:UNKNOWNPART',
                                  [('parttype', str(exc))])
        bundler.addpart(part)
        return streamres(bundler.getchunks())
    except util.Abort, inst:
        # The old code we moved used sys.stderr directly.
        # We did not change it to minimise code change.
        # This need to be moved to something proper.
        # Feel free to do it.
        if getattr(inst, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            manargs = [('message', str(inst))]
            advargs = []
            if inst.hint is not None:
                advargs.append(('hint', inst.hint))
            bundler.addpart(
                bundle2.bundlepart('B2X:ERROR:ABORT', manargs, advargs))
            return streamres(bundler.getchunks())
        else:
            sys.stderr.write("abort: %s\n" % inst)
            return pushres(0)
    except error.PushRaced, exc:
        if getattr(exc, 'duringunbundle2', False):
            bundler = bundle2.bundle20(repo.ui)
            part = bundle2.bundlepart('B2X:ERROR:PUSHRACED',
                                      [('message', str(exc))])
            bundler.addpart(part)
            return streamres(bundler.getchunks())
        else:
            return pusherr(str(exc))