Show More
@@ -588,6 +588,100 b' def _revisiondeltanormal(store, rev, pre' | |||
|
588 | 588 | deltachunks=(prefix, delta), |
|
589 | 589 | ) |
|
590 | 590 | |
|
591 | def _revisiondeltanarrow(cl, store, ischangelog, rev, linkrev, | |
|
592 | linknode, clrevtolocalrev, fullclnodes, | |
|
593 | precomputedellipsis): | |
|
594 | linkparents = precomputedellipsis[linkrev] | |
|
595 | def local(clrev): | |
|
596 | """Turn a changelog revnum into a local revnum. | |
|
597 | ||
|
598 | The ellipsis dag is stored as revnums on the changelog, | |
|
599 | but when we're producing ellipsis entries for | |
|
600 | non-changelog revlogs, we need to turn those numbers into | |
|
601 | something local. This does that for us, and during the | |
|
602 | changelog sending phase will also expand the stored | |
|
603 | mappings as needed. | |
|
604 | """ | |
|
605 | if clrev == nullrev: | |
|
606 | return nullrev | |
|
607 | ||
|
608 | if ischangelog: | |
|
609 | return clrev | |
|
610 | ||
|
611 | # Walk the ellipsis-ized changelog breadth-first looking for a | |
|
612 | # change that has been linked from the current revlog. | |
|
613 | # | |
|
614 | # For a flat manifest revlog only a single step should be necessary | |
|
615 | # as all relevant changelog entries are relevant to the flat | |
|
616 | # manifest. | |
|
617 | # | |
|
618 | # For a filelog or tree manifest dirlog however not every changelog | |
|
619 | # entry will have been relevant, so we need to skip some changelog | |
|
620 | # nodes even after ellipsis-izing. | |
|
621 | walk = [clrev] | |
|
622 | while walk: | |
|
623 | p = walk[0] | |
|
624 | walk = walk[1:] | |
|
625 | if p in clrevtolocalrev: | |
|
626 | return clrevtolocalrev[p] | |
|
627 | elif p in fullclnodes: | |
|
628 | walk.extend([pp for pp in cl.parentrevs(p) | |
|
629 | if pp != nullrev]) | |
|
630 | elif p in precomputedellipsis: | |
|
631 | walk.extend([pp for pp in precomputedellipsis[p] | |
|
632 | if pp != nullrev]) | |
|
633 | else: | |
|
634 | # In this case, we've got an ellipsis with parents | |
|
635 | # outside the current bundle (likely an | |
|
636 | # incremental pull). We "know" that we can use the | |
|
637 | # value of this same revlog at whatever revision | |
|
638 | # is pointed to by linknode. "Know" is in scare | |
|
639 | # quotes because I haven't done enough examination | |
|
640 | # of edge cases to convince myself this is really | |
|
641 | # a fact - it works for all the (admittedly | |
|
642 | # thorough) cases in our testsuite, but I would be | |
|
643 | # somewhat unsurprised to find a case in the wild | |
|
644 | # where this breaks down a bit. That said, I don't | |
|
645 | # know if it would hurt anything. | |
|
646 | for i in pycompat.xrange(rev, 0, -1): | |
|
647 | if store.linkrev(i) == clrev: | |
|
648 | return i | |
|
649 | # We failed to resolve a parent for this node, so | |
|
650 | # we crash the changegroup construction. | |
|
651 | raise error.Abort( | |
|
652 | 'unable to resolve parent while packing %r %r' | |
|
653 | ' for changeset %r' % (store.indexfile, rev, clrev)) | |
|
654 | ||
|
655 | return nullrev | |
|
656 | ||
|
657 | if not linkparents or ( | |
|
658 | store.parentrevs(rev) == (nullrev, nullrev)): | |
|
659 | p1, p2 = nullrev, nullrev | |
|
660 | elif len(linkparents) == 1: | |
|
661 | p1, = sorted(local(p) for p in linkparents) | |
|
662 | p2 = nullrev | |
|
663 | else: | |
|
664 | p1, p2 = sorted(local(p) for p in linkparents) | |
|
665 | ||
|
666 | n = store.node(rev) | |
|
667 | p1n, p2n = store.node(p1), store.node(p2) | |
|
668 | flags = store.flags(rev) | |
|
669 | flags |= revlog.REVIDX_ELLIPSIS | |
|
670 | ||
|
671 | # TODO: try and actually send deltas for ellipsis data blocks | |
|
672 | data = store.revision(n) | |
|
673 | diffheader = mdiff.trivialdiffheader(len(data)) | |
|
674 | ||
|
675 | return revisiondelta( | |
|
676 | node=n, | |
|
677 | p1node=p1n, | |
|
678 | p2node=p2n, | |
|
679 | basenode=nullid, | |
|
680 | linknode=linknode, | |
|
681 | flags=flags, | |
|
682 | deltachunks=(diffheader, data), | |
|
683 | ) | |
|
684 | ||
|
591 | 685 | class cgpacker(object): |
|
592 | 686 | def __init__(self, repo, filematcher, version, allowreorder, |
|
593 | 687 | deltaparentfn, builddeltaheader, manifestsend, |
@@ -707,7 +801,7 b' class cgpacker(object):' | |||
|
707 | 801 | elif linkrev not in self._precomputedellipsis: |
|
708 | 802 | delta = None |
|
709 | 803 | else: |
|
710 |
delta = |
|
|
804 | delta = _revisiondeltanarrow( | |
|
711 | 805 | cl, store, ischangelog, curr, linkrev, linknode, |
|
712 | 806 | clrevtolocalrev, self._fullclnodes, |
|
713 | 807 | self._precomputedellipsis) |
@@ -1058,100 +1152,6 b' class cgpacker(object):' | |||
|
1058 | 1152 | self._verbosenote(_('%8.i %s\n') % (size, fname)) |
|
1059 | 1153 | progress.complete() |
|
1060 | 1154 | |
|
1061 | def _revisiondeltanarrow(self, cl, store, ischangelog, rev, linkrev, | |
|
1062 | linknode, clrevtolocalrev, fullclnodes, | |
|
1063 | precomputedellipsis): | |
|
1064 | linkparents = precomputedellipsis[linkrev] | |
|
1065 | def local(clrev): | |
|
1066 | """Turn a changelog revnum into a local revnum. | |
|
1067 | ||
|
1068 | The ellipsis dag is stored as revnums on the changelog, | |
|
1069 | but when we're producing ellipsis entries for | |
|
1070 | non-changelog revlogs, we need to turn those numbers into | |
|
1071 | something local. This does that for us, and during the | |
|
1072 | changelog sending phase will also expand the stored | |
|
1073 | mappings as needed. | |
|
1074 | """ | |
|
1075 | if clrev == nullrev: | |
|
1076 | return nullrev | |
|
1077 | ||
|
1078 | if ischangelog: | |
|
1079 | return clrev | |
|
1080 | ||
|
1081 | # Walk the ellipsis-ized changelog breadth-first looking for a | |
|
1082 | # change that has been linked from the current revlog. | |
|
1083 | # | |
|
1084 | # For a flat manifest revlog only a single step should be necessary | |
|
1085 | # as all relevant changelog entries are relevant to the flat | |
|
1086 | # manifest. | |
|
1087 | # | |
|
1088 | # For a filelog or tree manifest dirlog however not every changelog | |
|
1089 | # entry will have been relevant, so we need to skip some changelog | |
|
1090 | # nodes even after ellipsis-izing. | |
|
1091 | walk = [clrev] | |
|
1092 | while walk: | |
|
1093 | p = walk[0] | |
|
1094 | walk = walk[1:] | |
|
1095 | if p in clrevtolocalrev: | |
|
1096 | return clrevtolocalrev[p] | |
|
1097 | elif p in fullclnodes: | |
|
1098 | walk.extend([pp for pp in cl.parentrevs(p) | |
|
1099 | if pp != nullrev]) | |
|
1100 | elif p in precomputedellipsis: | |
|
1101 | walk.extend([pp for pp in precomputedellipsis[p] | |
|
1102 | if pp != nullrev]) | |
|
1103 | else: | |
|
1104 | # In this case, we've got an ellipsis with parents | |
|
1105 | # outside the current bundle (likely an | |
|
1106 | # incremental pull). We "know" that we can use the | |
|
1107 | # value of this same revlog at whatever revision | |
|
1108 | # is pointed to by linknode. "Know" is in scare | |
|
1109 | # quotes because I haven't done enough examination | |
|
1110 | # of edge cases to convince myself this is really | |
|
1111 | # a fact - it works for all the (admittedly | |
|
1112 | # thorough) cases in our testsuite, but I would be | |
|
1113 | # somewhat unsurprised to find a case in the wild | |
|
1114 | # where this breaks down a bit. That said, I don't | |
|
1115 | # know if it would hurt anything. | |
|
1116 | for i in pycompat.xrange(rev, 0, -1): | |
|
1117 | if store.linkrev(i) == clrev: | |
|
1118 | return i | |
|
1119 | # We failed to resolve a parent for this node, so | |
|
1120 | # we crash the changegroup construction. | |
|
1121 | raise error.Abort( | |
|
1122 | 'unable to resolve parent while packing %r %r' | |
|
1123 | ' for changeset %r' % (store.indexfile, rev, clrev)) | |
|
1124 | ||
|
1125 | return nullrev | |
|
1126 | ||
|
1127 | if not linkparents or ( | |
|
1128 | store.parentrevs(rev) == (nullrev, nullrev)): | |
|
1129 | p1, p2 = nullrev, nullrev | |
|
1130 | elif len(linkparents) == 1: | |
|
1131 | p1, = sorted(local(p) for p in linkparents) | |
|
1132 | p2 = nullrev | |
|
1133 | else: | |
|
1134 | p1, p2 = sorted(local(p) for p in linkparents) | |
|
1135 | ||
|
1136 | n = store.node(rev) | |
|
1137 | p1n, p2n = store.node(p1), store.node(p2) | |
|
1138 | flags = store.flags(rev) | |
|
1139 | flags |= revlog.REVIDX_ELLIPSIS | |
|
1140 | ||
|
1141 | # TODO: try and actually send deltas for ellipsis data blocks | |
|
1142 | data = store.revision(n) | |
|
1143 | diffheader = mdiff.trivialdiffheader(len(data)) | |
|
1144 | ||
|
1145 | return revisiondelta( | |
|
1146 | node=n, | |
|
1147 | p1node=p1n, | |
|
1148 | p2node=p2n, | |
|
1149 | basenode=nullid, | |
|
1150 | linknode=linknode, | |
|
1151 | flags=flags, | |
|
1152 | deltachunks=(diffheader, data), | |
|
1153 | ) | |
|
1154 | ||
|
1155 | 1155 | def _deltaparentprev(store, rev, p1, p2, prev): |
|
1156 | 1156 | """Resolve a delta parent to the previous revision. |
|
1157 | 1157 |
General Comments 0
You need to be logged in to leave comments.
Login now