Show More
@@ -24,13 +24,13 b' from .thirdparty import (' | |||||
24 | ) |
|
24 | ) | |
25 |
|
25 | |||
26 | from . import ( |
|
26 | from . import ( | |
27 | dagop, |
|
|||
28 | error, |
|
27 | error, | |
29 | match as matchmod, |
|
28 | match as matchmod, | |
30 | mdiff, |
|
29 | mdiff, | |
31 | phases, |
|
30 | phases, | |
32 | pycompat, |
|
31 | pycompat, | |
33 | repository, |
|
32 | repository, | |
|
33 | revlog, | |||
34 | util, |
|
34 | util, | |
35 | ) |
|
35 | ) | |
36 |
|
36 | |||
@@ -536,18 +536,8 b' def _revisiondeltatochunks(delta, header' | |||||
536 | yield prefix |
|
536 | yield prefix | |
537 | yield data |
|
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 | def _sortnodesellipsis(store, nodes, cl, lookup): |
|
539 | def _sortnodesellipsis(store, nodes, cl, lookup): | |
550 |
"""Sort nodes for changegroup generation |
|
540 | """Sort nodes for changegroup generation.""" | |
551 | # Ellipses serving mode. |
|
541 | # Ellipses serving mode. | |
552 | # |
|
542 | # | |
553 | # In a perfect world, we'd generate better ellipsis-ified graphs |
|
543 | # In a perfect world, we'd generate better ellipsis-ified graphs | |
@@ -565,11 +555,11 b' def _sortnodesellipsis(store, nodes, cl,' | |||||
565 | # changelog, so what we do is we sort the non-changelog histories |
|
555 | # changelog, so what we do is we sort the non-changelog histories | |
566 | # by the order in which they are used by the changelog. |
|
556 | # by the order in which they are used by the changelog. | |
567 | key = lambda n: cl.rev(lookup(n)) |
|
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 | linknode, clrevtolocalrev, fullclnodes, |
|
561 | linknode, clrevtolocalrev, fullclnodes, | |
572 | precomputedellipsis): |
|
562 | precomputedellipsis): | |
573 | linkparents = precomputedellipsis[linkrev] |
|
563 | linkparents = precomputedellipsis[linkrev] | |
574 | def local(clrev): |
|
564 | def local(clrev): | |
575 | """Turn a changelog revnum into a local revnum. |
|
565 | """Turn a changelog revnum into a local revnum. | |
@@ -644,15 +634,7 b' def _makenarrowdeltarequest(cl, store, i' | |||||
644 |
|
634 | |||
645 | p1node, p2node = store.node(p1), store.node(p2) |
|
635 | p1node, p2node = store.node(p1), store.node(p2) | |
646 |
|
636 | |||
647 | # TODO: try and actually send deltas for ellipsis data blocks |
|
637 | return p1node, p2node, linknode | |
648 | return revisiondeltarequest( |
|
|||
649 | node=node, |
|
|||
650 | p1node=p1node, |
|
|||
651 | p2node=p2node, |
|
|||
652 | linknode=linknode, |
|
|||
653 | basenode=nullid, |
|
|||
654 | ellipsis=True, |
|
|||
655 | ) |
|
|||
656 |
|
638 | |||
657 | def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev, |
|
639 | def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev, | |
658 | topic=None, |
|
640 | topic=None, | |
@@ -668,87 +650,97 b' def deltagroup(repo, store, nodes, ischa' | |||||
668 | if not nodes: |
|
650 | if not nodes: | |
669 | return |
|
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 | cl = repo.changelog |
|
653 | cl = repo.changelog | |
682 |
|
654 | |||
683 | if ischangelog: |
|
655 | if ischangelog: | |
684 | # Changelog doesn't benefit from reordering revisions. So send |
|
656 | # `hg log` shows changesets in storage order. To preserve order | |
685 |
# |
|
657 | # across clones, send out changesets in storage order. | |
686 | # TODO the API would be cleaner if this were controlled by the |
|
658 | nodesorder = 'storage' | |
687 | # store producing the deltas. |
|
|||
688 | revs = sorted(cl.rev(n) for n in nodes) |
|
|||
689 | elif ellipses: |
|
659 | elif ellipses: | |
690 |
|
|
660 | nodes = _sortnodesellipsis(store, nodes, cl, lookup) | |
|
661 | nodesorder = 'nodes' | |||
691 | else: |
|
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 |
|
665 | # Perform ellipses filtering and revision massaging. We do this before | |
695 | # generating. |
|
666 | # emitrevisions() because a) filtering out revisions creates less work | |
696 | requests = [] |
|
667 | # for emitrevisions() b) dropping revisions would break emitrevisions()'s | |
697 |
|
668 | # assumptions about delta choices and we would possibly send a delta | ||
698 | # Add the parent of the first rev. |
|
669 | # referencing a missing base revision. | |
699 | revs.insert(0, store.parentrevs(revs[0])[0]) |
|
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): |
|
682 | for node in nodes: | |
702 |
|
|
683 | rev = store.rev(node) | |
703 | curr = revs[i + 1] |
|
684 | linknode = lookup(node) | |
704 |
|
||||
705 | node = store.node(curr) |
|
|||
706 | linknode = lookup(node) |
|
|||
707 | p1node, p2node = store.parents(node) |
|
|||
708 |
|
||||
709 | if ellipses: |
|
|||
710 | linkrev = cl.rev(linknode) |
|
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 |
|
688 | # If linknode is in fullclnodes, it means the corresponding | |
714 |
# c |
|
689 | # changeset was a full changeset and is being sent unaltered. | |
715 | if linknode in fullclnodes: |
|
690 | if linknode in fullclnodes: | |
716 | requests.append(revisiondeltarequest( |
|
691 | linknodes[node] = linknode | |
717 | node=node, |
|
|||
718 | p1node=p1node, |
|
|||
719 | p2node=p2node, |
|
|||
720 | linknode=linknode, |
|
|||
721 | basenode=None, |
|
|||
722 | )) |
|
|||
723 |
|
692 | |||
|
693 | # If the corresponding changeset wasn't in the set computed | |||
|
694 | # as relevant to us, it should be dropped outright. | |||
724 | elif linkrev not in precomputedellipsis: |
|
695 | elif linkrev not in precomputedellipsis: | |
725 |
|
|
696 | continue | |
|
697 | ||||
726 | else: |
|
698 | else: | |
727 | requests.append(_makenarrowdeltarequest( |
|
699 | # We could probably do this later and avoid the dict | |
728 | cl, store, ischangelog, curr, node, linkrev, linknode, |
|
700 | # holding state. But it likely doesn't matter. | |
729 | clrevtolocalrev, fullclnodes, |
|
701 | p1node, p2node, linknode = _resolvenarrowrevisioninfo( | |
730 | precomputedellipsis)) |
|
702 | cl, store, ischangelog, rev, linkrev, linknode, | |
731 | else: |
|
703 | clrevtolocalrev, fullclnodes, precomputedellipsis) | |
732 | requests.append(revisiondeltarequest( |
|
704 | ||
733 | node=node, |
|
705 | adjustedparents[node] = (p1node, p2node) | |
734 |
|
|
706 | linknodes[node] = linknode | |
735 | p2node=p2node, |
|
707 | ||
736 | linknode=linknode, |
|
708 | filtered.append(node) | |
737 | basenode=store.node(prev) if forcedeltaparentprev else None, |
|
709 | ||
738 | )) |
|
710 | nodes = filtered | |
739 |
|
711 | |||
740 | # We expect the first pass to be fast, so we only engage the progress |
|
712 | # We expect the first pass to be fast, so we only engage the progress | |
741 | # meter for constructing the revision deltas. |
|
713 | # meter for constructing the revision deltas. | |
742 | progress = None |
|
714 | progress = None | |
743 | if topic is not None: |
|
715 | if topic is not None: | |
744 | progress = repo.ui.makeprogress(topic, unit=_('chunks'), |
|
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 | if progress: |
|
727 | if progress: | |
749 | progress.update(i + 1) |
|
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 | if progress: |
|
745 | if progress: | |
754 | progress.complete() |
|
746 | progress.complete() |
General Comments 0
You need to be logged in to leave comments.
Login now