490 raise NotImplementedError |
490 raise NotImplementedError |
491 |
491 |
492 def release(self): |
492 def release(self): |
493 raise NotImplementedError |
493 raise NotImplementedError |
494 |
494 |
495 def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None, |
495 def getremotechanges(ui, repo, peer, onlyheads=None, bundlename=None, |
496 force=False): |
496 force=False): |
497 '''obtains a bundle of changes incoming from other |
497 '''obtains a bundle of changes incoming from peer |
498 |
498 |
499 "onlyheads" restricts the returned changes to those reachable from the |
499 "onlyheads" restricts the returned changes to those reachable from the |
500 specified heads. |
500 specified heads. |
501 "bundlename", if given, stores the bundle to this file path permanently; |
501 "bundlename", if given, stores the bundle to this file path permanently; |
502 otherwise it's stored to a temp file and gets deleted again when you call |
502 otherwise it's stored to a temp file and gets deleted again when you call |
505 |
505 |
506 Returns a tuple (local, csets, cleanupfn): |
506 Returns a tuple (local, csets, cleanupfn): |
507 |
507 |
508 "local" is a local repo from which to obtain the actual incoming |
508 "local" is a local repo from which to obtain the actual incoming |
509 changesets; it is a bundlerepo for the obtained bundle when the |
509 changesets; it is a bundlerepo for the obtained bundle when the |
510 original "other" is remote. |
510 original "peer" is remote. |
511 "csets" lists the incoming changeset node ids. |
511 "csets" lists the incoming changeset node ids. |
512 "cleanupfn" must be called without arguments when you're done processing |
512 "cleanupfn" must be called without arguments when you're done processing |
513 the changes; it closes both the original "other" and the one returned |
513 the changes; it closes both the original "peer" and the one returned |
514 here. |
514 here. |
515 ''' |
515 ''' |
516 tmp = discovery.findcommonincoming(repo, other, heads=onlyheads, |
516 tmp = discovery.findcommonincoming(repo, peer, heads=onlyheads, |
517 force=force) |
517 force=force) |
518 common, incoming, rheads = tmp |
518 common, incoming, rheads = tmp |
519 if not incoming: |
519 if not incoming: |
520 try: |
520 try: |
521 if bundlename: |
521 if bundlename: |
522 os.unlink(bundlename) |
522 os.unlink(bundlename) |
523 except OSError: |
523 except OSError: |
524 pass |
524 pass |
525 return repo, [], other.close |
525 return repo, [], peer.close |
526 |
526 |
527 commonset = set(common) |
527 commonset = set(common) |
528 rheads = [x for x in rheads if x not in commonset] |
528 rheads = [x for x in rheads if x not in commonset] |
529 |
529 |
530 bundle = None |
530 bundle = None |
531 bundlerepo = None |
531 bundlerepo = None |
532 localrepo = other.local() |
532 localrepo = peer.local() |
533 if bundlename or not localrepo: |
533 if bundlename or not localrepo: |
534 # create a bundle (uncompressed if other repo is not local) |
534 # create a bundle (uncompressed if peer repo is not local) |
535 |
535 |
536 # developer config: devel.legacy.exchange |
536 # developer config: devel.legacy.exchange |
537 legexc = ui.configlist('devel', 'legacy.exchange') |
537 legexc = ui.configlist('devel', 'legacy.exchange') |
538 forcebundle1 = 'bundle2' not in legexc and 'bundle1' in legexc |
538 forcebundle1 = 'bundle2' not in legexc and 'bundle1' in legexc |
539 canbundle2 = (not forcebundle1 |
539 canbundle2 = (not forcebundle1 |
540 and other.capable('getbundle') |
540 and peer.capable('getbundle') |
541 and other.capable('bundle2')) |
541 and peer.capable('bundle2')) |
542 if canbundle2: |
542 if canbundle2: |
543 kwargs = {} |
543 kwargs = {} |
544 kwargs[r'common'] = common |
544 kwargs[r'common'] = common |
545 kwargs[r'heads'] = rheads |
545 kwargs[r'heads'] = rheads |
546 kwargs[r'bundlecaps'] = exchange.caps20to10(repo, role='client') |
546 kwargs[r'bundlecaps'] = exchange.caps20to10(repo, role='client') |
547 kwargs[r'cg'] = True |
547 kwargs[r'cg'] = True |
548 b2 = other.getbundle('incoming', **kwargs) |
548 b2 = peer.getbundle('incoming', **kwargs) |
549 fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(), |
549 fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(), |
550 bundlename) |
550 bundlename) |
551 else: |
551 else: |
552 if other.capable('getbundle'): |
552 if peer.capable('getbundle'): |
553 cg = other.getbundle('incoming', common=common, heads=rheads) |
553 cg = peer.getbundle('incoming', common=common, heads=rheads) |
554 elif onlyheads is None and not other.capable('changegroupsubset'): |
554 elif onlyheads is None and not peer.capable('changegroupsubset'): |
555 # compat with older servers when pulling all remote heads |
555 # compat with older servers when pulling all remote heads |
556 |
556 |
557 with other.commandexecutor() as e: |
557 with peer.commandexecutor() as e: |
558 cg = e.callcommand('changegroup', { |
558 cg = e.callcommand('changegroup', { |
559 'nodes': incoming, |
559 'nodes': incoming, |
560 'source': 'incoming', |
560 'source': 'incoming', |
561 }).result() |
561 }).result() |
562 |
562 |
563 rheads = None |
563 rheads = None |
564 else: |
564 else: |
565 with other.commandexecutor() as e: |
565 with peer.commandexecutor() as e: |
566 cg = e.callcommand('changegroupsubset', { |
566 cg = e.callcommand('changegroupsubset', { |
567 'bases': incoming, |
567 'bases': incoming, |
568 'heads': rheads, |
568 'heads': rheads, |
569 'source': 'incoming', |
569 'source': 'incoming', |
570 }).result() |
570 }).result() |
592 |
592 |
593 csets = localrepo.changelog.findmissing(common, rheads) |
593 csets = localrepo.changelog.findmissing(common, rheads) |
594 |
594 |
595 if bundlerepo: |
595 if bundlerepo: |
596 reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]] |
596 reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]] |
597 remotephases = other.listkeys('phases') |
597 remotephases = peer.listkeys('phases') |
598 |
598 |
599 pullop = exchange.pulloperation(bundlerepo, other, heads=reponodes) |
599 pullop = exchange.pulloperation(bundlerepo, peer, heads=reponodes) |
600 pullop.trmanager = bundletransactionmanager() |
600 pullop.trmanager = bundletransactionmanager() |
601 exchange._pullapplyphases(pullop, remotephases) |
601 exchange._pullapplyphases(pullop, remotephases) |
602 |
602 |
603 def cleanup(): |
603 def cleanup(): |
604 if bundlerepo: |
604 if bundlerepo: |
605 bundlerepo.close() |
605 bundlerepo.close() |
606 if bundle: |
606 if bundle: |
607 os.unlink(bundle) |
607 os.unlink(bundle) |
608 other.close() |
608 peer.close() |
609 |
609 |
610 return (localrepo, csets, cleanup) |
610 return (localrepo, csets, cleanup) |