예제 #1
0
def create_bundle(store, commits, bundle2caps={}):
    version = b'01'
    chunk_type = RawRevChunk01
    if bundle2caps:
        versions = bundle2caps.get(b'changegroup')
        if versions:
            if b'02' in versions:
                chunk_type = RawRevChunk02
                version = b'02'
    cg = create_changegroup(store, bundle_data(store, commits), chunk_type)
    if bundle2caps:
        yield b'HG20'
        yield b'\0' * 4  # bundle parameters length: no params
        replycaps = bundle2caps.get(b'replycaps')
        if replycaps:
            for chunk in bundlepart(b'REPLYCAPS',
                                    data=chunkbuffer([replycaps])):
                yield chunk
        for chunk in bundlepart(b'CHANGEGROUP',
                                advisoryparams=((b'version', version), ),
                                data=chunkbuffer(cg)):
            yield chunk
        yield b'\0' * 4  # End of bundle
    else:
        for chunk in cg:
            yield chunk
예제 #2
0
def create_bundle(store, commits, bundle2caps={}):
    version = '01'
    chunk_type = RawRevChunk01
    if bundle2caps:
        versions = bundle2caps.get('changegroup')
        if versions:
            if '02' in versions:
                chunk_type = RawRevChunk02
                version = '02'
    cg = create_changegroup(store, bundle_data(store, commits), chunk_type)
    if bundle2caps:
        yield 'HG20'
        yield '\0' * 4  # bundle parameters length: no params
        replycaps = bundle2caps.get('replycaps')
        if replycaps:
            for chunk in bundlepart('REPLYCAPS', data=chunkbuffer(replycaps)):
                yield chunk
        for chunk in bundlepart('CHANGEGROUP',
                                advisoryparams=(('version', version),),
                                data=chunkbuffer(cg)):
            yield chunk
        yield '\0' * 4  # End of bundle
    else:
        for chunk in cg:
            yield chunk
예제 #3
0
def push(repo, store, what, repo_heads, repo_branches, dry_run=False):
    def heads():
        for sha1 in store.heads(repo_branches):
            yield b'^%s' % store.changeset_ref(sha1)

    def local_bases():
        h = chain(heads(), (w for w, _, _ in what if w))
        for c, t, p in GitHgHelper.rev_list(b'--topo-order', b'--full-history',
                                            b'--boundary', *h):
            if c[:1] != b'-':
                continue
            yield store.hg_changeset(c[1:])

        for w, _, _ in what:
            if w:
                rev = store.hg_changeset(w)
                if rev:
                    yield rev

    common = findcommon(repo, store, set(local_bases()))
    logging.info('common: %s', common)

    def revs():
        for sha1 in common:
            yield b'^%s' % store.changeset_ref(sha1)

    revs = chain(revs(), (w for w, _, _ in what if w))
    push_commits = list((c, p) for c, t, p in GitHgHelper.rev_list(
        b'--topo-order', b'--full-history', b'--parents', b'--reverse', *revs))

    pushed = False
    if push_commits:
        has_root = any(not p for (c, p) in push_commits)
        force = all(v for _, _, v in what)
        if has_root and repo_heads:
            if not force:
                raise Exception('Cannot push a new root')
            else:
                logging.warn('Pushing a new root')
        if force:
            repo_heads = [b'force']
        else:
            if not repo_heads:
                repo_heads = [NULL_NODE_ID]
            repo_heads = [unhexlify(h) for h in repo_heads]
    if push_commits and not dry_run:
        if repo.local():
            repo.local().ui.setconfig(b'server', b'validate', True)
        if unbundle20:
            b2caps = repo.capable(b'bundle2') or {}
        else:
            b2caps = {}
        if b2caps:
            b2caps = decodecaps(unquote_to_bytes(b2caps))
        logging.getLogger('bundle2').debug('%r', b2caps)
        if b2caps:
            b2caps[b'replycaps'] = encodecaps({b'error': [b'abort']})
        cg = create_bundle(store, push_commits, b2caps)
        if not isinstance(repo, HelperRepo):
            cg = chunkbuffer(cg)
            if not b2caps:
                cg = cg1unpacker(cg, b'UN')
        reply = repo.unbundle(cg, repo_heads, b'')
        if unbundle20 and isinstance(reply, unbundle20):
            parts = iter(reply.iterparts())
            for part in parts:
                logging.getLogger('bundle2').debug('part: %s', part.type)
                logging.getLogger('bundle2').debug('params: %r', part.params)
                if part.type == b'output':
                    sys.stderr.write(fsdecode(part.read()))
                elif part.type == b'reply:changegroup':
                    # TODO: should check params['in-reply-to']
                    reply = int(part.params[b'return'])
                elif part.type == b'error:abort':
                    message = part.params[b'message'].decode('utf-8')
                    hint = part.params.get(b'hint')
                    if hint:
                        message += '\n\n' + hint.decode('utf-8')
                    raise Exception(message)
                else:
                    logging.getLogger(b'bundle2').warning(
                        'ignoring bundle2 part: %s', part.type)
        pushed = reply != 0
    return gitdag(push_commits) if pushed or dry_run else ()
예제 #4
0
def push(repo, store, what, repo_heads, repo_branches, dry_run=False):
    def heads():
        for sha1 in store.heads(repo_branches):
            yield '^%s' % store.changeset_ref(sha1)

    def local_bases():
        h = chain(heads(), (w for w in what if w))
        for c, t, p in GitHgHelper.rev_list('--topo-order', '--full-history',
                                            '--boundary', *h):
            if c[0] != '-':
                continue
            yield store.hg_changeset(c[1:])

        for w in what:
            rev = store.hg_changeset(w)
            if rev:
                yield rev

    common = findcommon(repo, store, set(local_bases()))
    logging.info('common: %s', common)

    def revs():
        for sha1 in common:
            yield '^%s' % store.changeset_ref(sha1)

    revs = chain(revs(), (w for w in what if w))
    push_commits = list((c, p) for c, t, p in GitHgHelper.rev_list(
        '--topo-order', '--full-history', '--parents', '--reverse', *revs))

    pushed = False
    if push_commits:
        has_root = any(len(p) == 40 for p in push_commits)
        force = all(v[1] for v in what.values())
        if has_root and repo_heads:
            if not force:
                raise Exception('Cannot push a new root')
            else:
                logging.warn('Pushing a new root')
        if force:
            repo_heads = ['force']
        else:
            if not repo_heads:
                repo_heads = [NULL_NODE_ID]
            repo_heads = [unhexlify(h) for h in repo_heads]
    if push_commits and not dry_run:
        if repo.local():
            repo.local().ui.setconfig('server', 'validate', True)
        b2caps = bundle2caps(repo) if unbundle20 else {}
        logging.getLogger('bundle2').debug('%r', b2caps)
        if b2caps:
            b2caps['replycaps'] = encodecaps({'error': ['abort']})
        cg = create_bundle(store, push_commits, b2caps)
        if not isinstance(repo, HelperRepo):
            cg = chunkbuffer(cg)
            if not b2caps:
                cg = cg1unpacker(cg, 'UN')
        reply = repo.unbundle(cg, repo_heads, '')
        if unbundle20 and isinstance(reply, unbundle20):
            parts = iter(reply.iterparts())
            for part in parts:
                logging.getLogger('bundle2').debug('part: %s', part.type)
                logging.getLogger('bundle2').debug('params: %r', part.params)
                if part.type == 'output':
                    sys.stderr.write(part.read())
                elif part.type == 'reply:changegroup':
                    # TODO: should check params['in-reply-to']
                    reply = int(part.params['return'])
                elif part.type == 'error:abort':
                    raise error.Abort(part.params['message'],
                                      hint=part.params.get('hint'))
                else:
                    logging.getLogger('bundle2').warning(
                        'ignoring bundle2 part: %s', part.type)
        pushed = reply != 0
    return gitdag(push_commits) if pushed or dry_run else ()
예제 #5
0
def push(repo, store, what, repo_heads, repo_branches, dry_run=False):
    def heads():
        for sha1 in store.heads(repo_branches):
            yield '^%s' % store.changeset_ref(sha1)

    def local_bases():
        h = chain(heads(), (w for w in what if w))
        for c, t, p in GitHgHelper.rev_list('--topo-order', '--full-history',
                                            '--boundary', *h):
            if c[0] != '-':
                continue
            yield store.hg_changeset(c[1:])

        for w in what:
            rev = store.hg_changeset(w)
            if rev:
                yield rev

    common = findcommon(repo, store, set(local_bases()))
    logging.info('common: %s', common)

    def revs():
        for sha1 in common:
            yield '^%s' % store.changeset_ref(sha1)

    revs = chain(revs(), (w for w in what if w))
    push_commits = list((c, p) for c, t, p in GitHgHelper.rev_list(
        '--topo-order', '--full-history', '--parents', '--reverse', *revs))

    pushed = False
    if push_commits:
        has_root = any(len(p) == 40 for p in push_commits)
        force = all(v[1] for v in what.values())
        if has_root and repo_heads:
            if not force:
                raise Exception('Cannot push a new root')
            else:
                logging.warn('Pushing a new root')
        if force:
            repo_heads = ['force']
        else:
            if not repo_heads:
                repo_heads = [NULL_NODE_ID]
            repo_heads = [unhexlify(h) for h in repo_heads]
    if push_commits and not dry_run:
        if repo.local():
            repo.local().ui.setconfig('server', 'validate', True)
        if unbundle20:
            b2caps = repo.capable('bundle2') or {}
        else:
            b2caps = {}
        if b2caps:
            b2caps = decodecaps(urllib.unquote(b2caps))
        logging.getLogger('bundle2').debug('%r', b2caps)
        if b2caps:
            b2caps['replycaps'] = encodecaps({'error': ['abort']})
        cg = create_bundle(store, push_commits, b2caps)
        if not isinstance(repo, HelperRepo):
            cg = chunkbuffer(cg)
            if not b2caps:
                cg = cg1unpacker(cg, 'UN')
        reply = repo.unbundle(cg, repo_heads, '')
        if unbundle20 and isinstance(reply, unbundle20):
            parts = iter(reply.iterparts())
            for part in parts:
                logging.getLogger('bundle2').debug('part: %s', part.type)
                logging.getLogger('bundle2').debug('params: %r', part.params)
                if part.type == 'output':
                    sys.stderr.write(part.read())
                elif part.type == 'reply:changegroup':
                    # TODO: should check params['in-reply-to']
                    reply = int(part.params['return'])
                elif part.type == 'error:abort':
                    raise error.Abort(part.params['message'],
                                      hint=part.params.get('hint'))
                else:
                    logging.getLogger('bundle2').warning(
                        'ignoring bundle2 part: %s', part.type)
        pushed = reply != 0
    return gitdag(push_commits) if pushed or dry_run else ()