comparison mercurial/wireprotov2server.py @ 39815:d3d333ab167a

wireprotov2: teach changesetdata to fetch ancestors until depth For shallow clone, it is useful to specify a starting node and tell the server to send up to N ancestors from that starting point. This enables the server to perform the DAG walk without the client having to discover the base/stop node(s) first. This commit implements support for said queries on the changesetdata command. Differential Revision: https://phab.mercurial-scm.org/D4621
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 17 Sep 2018 11:50:59 -0700
parents d059cb669632
children 3ed53b071041
comparison
equal deleted inserted replaced
39814:d059cb669632 39815:d3d333ab167a
655 }, 655 },
656 'nodes': { 656 'nodes': {
657 'type': 'list', 657 'type': 'list',
658 'example': [b'0123456...'], 658 'example': [b'0123456...'],
659 }, 659 },
660 'nodesdepth': {
661 'type': 'int',
662 'example': 10,
663 },
660 'fields': { 664 'fields': {
661 'type': 'set', 665 'type': 'set',
662 'default': set, 666 'default': set,
663 'example': {b'parents', b'revision'}, 667 'example': {b'parents', b'revision'},
664 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'}, 668 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
665 }, 669 },
666 }, 670 },
667 permission='pull') 671 permission='pull')
668 def changesetdata(repo, proto, noderange, nodes, fields): 672 def changesetdata(repo, proto, noderange, nodes, nodesdepth, fields):
669 # TODO look for unknown fields and abort when they can't be serviced. 673 # TODO look for unknown fields and abort when they can't be serviced.
670 # This could probably be validated by dispatcher using validvalues. 674 # This could probably be validated by dispatcher using validvalues.
671 675
672 if noderange is None and nodes is None: 676 if noderange is None and nodes is None:
673 raise error.WireprotoCommandError( 677 raise error.WireprotoCommandError(
674 'noderange or nodes must be defined') 678 'noderange or nodes must be defined')
679
680 if nodesdepth is not None and nodes is None:
681 raise error.WireprotoCommandError(
682 'nodesdepth requires the nodes argument')
675 683
676 if noderange is not None: 684 if noderange is not None:
677 if len(noderange) != 2: 685 if len(noderange) != 2:
678 raise error.WireprotoCommandError( 686 raise error.WireprotoCommandError(
679 'noderange must consist of 2 elements') 687 'noderange must consist of 2 elements')
687 695
688 seen = set() 696 seen = set()
689 outgoing = [] 697 outgoing = []
690 698
691 if nodes is not None: 699 if nodes is not None:
692 outgoing.extend(n for n in nodes if hasnode(n)) 700 outgoing = [n for n in nodes if hasnode(n)]
701
702 if nodesdepth:
703 outgoing = [cl.node(r) for r in
704 repo.revs(b'ancestors(%ln, %d)', outgoing,
705 nodesdepth - 1)]
706
693 seen |= set(outgoing) 707 seen |= set(outgoing)
694 708
695 if noderange is not None: 709 if noderange is not None:
696 if noderange[0]: 710 if noderange[0]:
697 common = [n for n in noderange[0] if hasnode(n)] 711 common = [n for n in noderange[0] if hasnode(n)]