Show More
@@ -24,13 +24,13 b' from .thirdparty import (' | |||
|
24 | 24 | ) |
|
25 | 25 | |
|
26 | 26 | from . import ( |
|
27 | dagop, | |
|
28 | 27 | error, |
|
29 | 28 | match as matchmod, |
|
30 | 29 | mdiff, |
|
31 | 30 | phases, |
|
32 | 31 | pycompat, |
|
33 | 32 | repository, |
|
33 | revlog, | |
|
34 | 34 | util, |
|
35 | 35 | ) |
|
36 | 36 | |
@@ -536,18 +536,8 b' def _revisiondeltatochunks(delta, header' | |||
|
536 | 536 | yield prefix |
|
537 | 537 | yield data |
|
538 | 538 | |
|
539 | def _sortnodesnormal(store, nodes): | |
|
540 | """Sort nodes for changegroup generation and turn into revnums.""" | |
|
541 | # for generaldelta revlogs, we linearize the revs; this will both be | |
|
542 | # much quicker and generate a much smaller bundle | |
|
543 | if store._generaldelta: | |
|
544 | revs = set(store.rev(n) for n in nodes) | |
|
545 | return dagop.linearize(revs, store.parentrevs) | |
|
546 | else: | |
|
547 | return sorted([store.rev(n) for n in nodes]) | |
|
548 | ||
|
549 | 539 | def _sortnodesellipsis(store, nodes, cl, lookup): |
|
550 |
"""Sort nodes for changegroup generation |
|
|
540 | """Sort nodes for changegroup generation.""" | |
|
551 | 541 | # Ellipses serving mode. |
|
552 | 542 | # |
|
553 | 543 | # In a perfect world, we'd generate better ellipsis-ified graphs |
@@ -565,9 +555,9 b' def _sortnodesellipsis(store, nodes, cl,' | |||
|
565 | 555 | # changelog, so what we do is we sort the non-changelog histories |
|
566 | 556 | # by the order in which they are used by the changelog. |
|
567 | 557 | key = lambda n: cl.rev(lookup(n)) |
|
568 |
return |
|
|
558 | return sorted(nodes, key=key) | |
|
569 | 559 | |
|
570 |
def _ |
|
|
560 | def _resolvenarrowrevisioninfo(cl, store, ischangelog, rev, linkrev, | |
|
571 | 561 | linknode, clrevtolocalrev, fullclnodes, |
|
572 | 562 | precomputedellipsis): |
|
573 | 563 | linkparents = precomputedellipsis[linkrev] |
@@ -644,15 +634,7 b' def _makenarrowdeltarequest(cl, store, i' | |||
|
644 | 634 | |
|
645 | 635 | p1node, p2node = store.node(p1), store.node(p2) |
|
646 | 636 | |
|
647 | # TODO: try and actually send deltas for ellipsis data blocks | |
|
648 | return revisiondeltarequest( | |
|
649 | node=node, | |
|
650 | p1node=p1node, | |
|
651 | p2node=p2node, | |
|
652 | linknode=linknode, | |
|
653 | basenode=nullid, | |
|
654 | ellipsis=True, | |
|
655 | ) | |
|
637 | return p1node, p2node, linknode | |
|
656 | 638 | |
|
657 | 639 | def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev, |
|
658 | 640 | topic=None, |
@@ -668,87 +650,97 b' def deltagroup(repo, store, nodes, ischa' | |||
|
668 | 650 | if not nodes: |
|
669 | 651 | return |
|
670 | 652 | |
|
671 | # We perform two passes over the revisions whose data we will emit. | |
|
672 | # | |
|
673 | # In the first pass, we obtain information about the deltas that will | |
|
674 | # be generated. This involves computing linknodes and adjusting the | |
|
675 | # request to take shallow fetching into account. The end result of | |
|
676 | # this pass is a list of "request" objects stating which deltas | |
|
677 | # to obtain. | |
|
678 | # | |
|
679 | # The second pass is simply resolving the requested deltas. | |
|
680 | ||
|
681 | 653 | cl = repo.changelog |
|
682 | 654 | |
|
683 | 655 | if ischangelog: |
|
684 | # Changelog doesn't benefit from reordering revisions. So send | |
|
685 |
# |
|
|
686 | # TODO the API would be cleaner if this were controlled by the | |
|
687 | # store producing the deltas. | |
|
688 | revs = sorted(cl.rev(n) for n in nodes) | |
|
656 | # `hg log` shows changesets in storage order. To preserve order | |
|
657 | # across clones, send out changesets in storage order. | |
|
658 | nodesorder = 'storage' | |
|
689 | 659 | elif ellipses: |
|
690 |
|
|
|
660 | nodes = _sortnodesellipsis(store, nodes, cl, lookup) | |
|
661 | nodesorder = 'nodes' | |
|
691 | 662 | else: |
|
692 | revs = _sortnodesnormal(store, nodes) | |
|
663 | nodesorder = None | |
|
693 | 664 | |
|
694 | # In the first pass, collect info about the deltas we'll be | |
|
695 | # generating. | |
|
696 | requests = [] | |
|
697 | ||
|
698 | # Add the parent of the first rev. | |
|
699 | revs.insert(0, store.parentrevs(revs[0])[0]) | |
|
665 | # Perform ellipses filtering and revision massaging. We do this before | |
|
666 | # emitrevisions() because a) filtering out revisions creates less work | |
|
667 | # for emitrevisions() b) dropping revisions would break emitrevisions()'s | |
|
668 | # assumptions about delta choices and we would possibly send a delta | |
|
669 | # referencing a missing base revision. | |
|
670 | # | |
|
671 | # Also, calling lookup() has side-effects with regards to populating | |
|
672 | # data structures. If we don't call lookup() for each node or if we call | |
|
673 | # lookup() after the first pass through each node, things can break - | |
|
674 | # possibly intermittently depending on the python hash seed! For that | |
|
675 | # reason, we store a mapping of all linknodes during the initial node | |
|
676 | # pass rather than use lookup() on the output side. | |
|
677 | if ellipses: | |
|
678 | filtered = [] | |
|
679 | adjustedparents = {} | |
|
680 | linknodes = {} | |
|
700 | 681 | |
|
701 | for i in pycompat.xrange(len(revs) - 1): | |
|
702 |
|
|
|
703 | curr = revs[i + 1] | |
|
704 | ||
|
705 | node = store.node(curr) | |
|
682 | for node in nodes: | |
|
683 | rev = store.rev(node) | |
|
706 | 684 | linknode = lookup(node) |
|
707 | p1node, p2node = store.parents(node) | |
|
708 | ||
|
709 | if ellipses: | |
|
710 | 685 | linkrev = cl.rev(linknode) |
|
711 |
clrevtolocalrev[linkrev] = |
|
|
686 | clrevtolocalrev[linkrev] = rev | |
|
712 | 687 | |
|
713 | # This is a node to send in full, because the changeset it | |
|
714 |
# c |
|
|
688 | # If linknode is in fullclnodes, it means the corresponding | |
|
689 | # changeset was a full changeset and is being sent unaltered. | |
|
715 | 690 | if linknode in fullclnodes: |
|
716 | requests.append(revisiondeltarequest( | |
|
717 | node=node, | |
|
718 | p1node=p1node, | |
|
719 | p2node=p2node, | |
|
720 | linknode=linknode, | |
|
721 | basenode=None, | |
|
722 | )) | |
|
691 | linknodes[node] = linknode | |
|
723 | 692 | |
|
693 | # If the corresponding changeset wasn't in the set computed | |
|
694 | # as relevant to us, it should be dropped outright. | |
|
724 | 695 | elif linkrev not in precomputedellipsis: |
|
725 |
|
|
|
726 | else: | |
|
727 | requests.append(_makenarrowdeltarequest( | |
|
728 | cl, store, ischangelog, curr, node, linkrev, linknode, | |
|
729 | clrevtolocalrev, fullclnodes, | |
|
730 | precomputedellipsis)) | |
|
696 | continue | |
|
697 | ||
|
731 | 698 | else: |
|
732 | requests.append(revisiondeltarequest( | |
|
733 | node=node, | |
|
734 | p1node=p1node, | |
|
735 | p2node=p2node, | |
|
736 | linknode=linknode, | |
|
737 | basenode=store.node(prev) if forcedeltaparentprev else None, | |
|
738 | )) | |
|
699 | # We could probably do this later and avoid the dict | |
|
700 | # holding state. But it likely doesn't matter. | |
|
701 | p1node, p2node, linknode = _resolvenarrowrevisioninfo( | |
|
702 | cl, store, ischangelog, rev, linkrev, linknode, | |
|
703 | clrevtolocalrev, fullclnodes, precomputedellipsis) | |
|
704 | ||
|
705 | adjustedparents[node] = (p1node, p2node) | |
|
706 | linknodes[node] = linknode | |
|
707 | ||
|
708 | filtered.append(node) | |
|
709 | ||
|
710 | nodes = filtered | |
|
739 | 711 | |
|
740 | 712 | # We expect the first pass to be fast, so we only engage the progress |
|
741 | 713 | # meter for constructing the revision deltas. |
|
742 | 714 | progress = None |
|
743 | 715 | if topic is not None: |
|
744 | 716 | progress = repo.ui.makeprogress(topic, unit=_('chunks'), |
|
745 |
total=len( |
|
|
717 | total=len(nodes)) | |
|
746 | 718 | |
|
747 | for i, delta in enumerate(store.emitrevisiondeltas(requests)): | |
|
719 | revisions = store.emitrevisions( | |
|
720 | nodes, | |
|
721 | nodesorder=nodesorder, | |
|
722 | revisiondata=True, | |
|
723 | assumehaveparentrevisions=not ellipses, | |
|
724 | deltaprevious=forcedeltaparentprev) | |
|
725 | ||
|
726 | for i, revision in enumerate(revisions): | |
|
748 | 727 | if progress: |
|
749 | 728 | progress.update(i + 1) |
|
750 | 729 | |
|
751 |
|
|
|
730 | if ellipses: | |
|
731 | linknode = linknodes[revision.node] | |
|
732 | ||
|
733 | if revision.node in adjustedparents: | |
|
734 | p1node, p2node = adjustedparents[revision.node] | |
|
735 | revision.p1node = p1node | |
|
736 | revision.p2node = p2node | |
|
737 | revision.flags |= revlog.REVIDX_ELLIPSIS | |
|
738 | ||
|
739 | else: | |
|
740 | linknode = lookup(revision.node) | |
|
741 | ||
|
742 | revision.linknode = linknode | |
|
743 | yield revision | |
|
752 | 744 | |
|
753 | 745 | if progress: |
|
754 | 746 | progress.complete() |
General Comments 0
You need to be logged in to leave comments.
Login now