458 |
462 |
459 @wireprotocommand('capabilities', permission='pull') |
463 @wireprotocommand('capabilities', permission='pull') |
460 def capabilitiesv2(repo, proto): |
464 def capabilitiesv2(repo, proto): |
461 yield _capabilitiesv2(repo, proto) |
465 yield _capabilitiesv2(repo, proto) |
462 |
466 |
|
467 @wireprotocommand('changesetdata', |
|
468 args={ |
|
469 'noderange': [[b'0123456...'], [b'abcdef...']], |
|
470 'nodes': [b'0123456...'], |
|
471 'fields': {b'parents', b'revision'}, |
|
472 }, |
|
473 permission='pull') |
|
474 def changesetdata(repo, proto, noderange=None, nodes=None, fields=None): |
|
475 fields = fields or set() |
|
476 |
|
477 if noderange is None and nodes is None: |
|
478 raise error.WireprotoCommandError( |
|
479 'noderange or nodes must be defined') |
|
480 |
|
481 if noderange is not None: |
|
482 if len(noderange) != 2: |
|
483 raise error.WireprotoCommandError( |
|
484 'noderange must consist of 2 elements') |
|
485 |
|
486 if not noderange[1]: |
|
487 raise error.WireprotoCommandError( |
|
488 'heads in noderange request cannot be empty') |
|
489 |
|
490 cl = repo.changelog |
|
491 hasnode = cl.hasnode |
|
492 |
|
493 seen = set() |
|
494 outgoing = [] |
|
495 |
|
496 if nodes is not None: |
|
497 outgoing.extend(n for n in nodes if hasnode(n)) |
|
498 seen |= set(outgoing) |
|
499 |
|
500 if noderange is not None: |
|
501 if noderange[0]: |
|
502 common = [n for n in noderange[0] if hasnode(n)] |
|
503 else: |
|
504 common = [nullid] |
|
505 |
|
506 for n in discovery.outgoing(repo, common, noderange[1]).missing: |
|
507 if n not in seen: |
|
508 outgoing.append(n) |
|
509 # Don't need to add to seen here because this is the final |
|
510 # source of nodes and there should be no duplicates in this |
|
511 # list. |
|
512 |
|
513 seen.clear() |
|
514 |
|
515 if outgoing: |
|
516 repo.hook('preoutgoing', throw=True, source='serve') |
|
517 |
|
518 yield { |
|
519 b'totalitems': len(outgoing), |
|
520 } |
|
521 |
|
522 # It is already topologically sorted by revision number. |
|
523 for node in outgoing: |
|
524 d = { |
|
525 b'node': node, |
|
526 } |
|
527 |
|
528 if b'parents' in fields: |
|
529 d[b'parents'] = cl.parents(node) |
|
530 |
|
531 revisiondata = None |
|
532 |
|
533 if b'revision' in fields: |
|
534 revisiondata = cl.revision(node, raw=True) |
|
535 d[b'revisionsize'] = len(revisiondata) |
|
536 |
|
537 yield d |
|
538 |
|
539 if revisiondata is not None: |
|
540 yield revisiondata |
|
541 |
463 @wireprotocommand('heads', |
542 @wireprotocommand('heads', |
464 args={ |
543 args={ |
465 'publiconly': False, |
544 'publiconly': False, |
466 }, |
545 }, |
467 permission='pull') |
546 permission='pull') |