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
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
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 ()
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 ()
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 ()