Show More
@@ -587,11 +587,37 b' def _sortnodesellipsis(store, nodes, cl,' | |||||
587 | key = lambda n: cl.rev(lookup(n)) |
|
587 | key = lambda n: cl.rev(lookup(n)) | |
588 | return [store.rev(n) for n in sorted(nodes, key=key)] |
|
588 | return [store.rev(n) for n in sorted(nodes, key=key)] | |
589 |
|
589 | |||
590 |
def _revisiondeltanormal(store, rev, prev, linknode, deltaparent |
|
590 | def _revisiondeltanormal(store, rev, prev, linknode, forcedeltaparentprev): | |
591 | """Construct a revision delta for non-ellipses changegroup generation.""" |
|
591 | """Construct a revision delta for non-ellipses changegroup generation.""" | |
592 | node = store.node(rev) |
|
592 | node = store.node(rev) | |
593 | p1, p2 = store.parentrevs(rev) |
|
593 | p1, p2 = store.parentrevs(rev) | |
594 | base = deltaparentfn(store, rev, p1, p2, prev) |
|
594 | ||
|
595 | if forcedeltaparentprev: | |||
|
596 | base = prev | |||
|
597 | else: | |||
|
598 | dp = store.deltaparent(rev) | |||
|
599 | ||||
|
600 | if dp == nullrev and store.storedeltachains: | |||
|
601 | # Avoid sending full revisions when delta parent is null. Pick prev | |||
|
602 | # in that case. It's tempting to pick p1 in this case, as p1 will | |||
|
603 | # be smaller in the common case. However, computing a delta against | |||
|
604 | # p1 may require resolving the raw text of p1, which could be | |||
|
605 | # expensive. The revlog caches should have prev cached, meaning | |||
|
606 | # less CPU for changegroup generation. There is likely room to add | |||
|
607 | # a flag and/or config option to control this behavior. | |||
|
608 | base = prev | |||
|
609 | elif dp == nullrev: | |||
|
610 | # revlog is configured to use full snapshot for a reason, | |||
|
611 | # stick to full snapshot. | |||
|
612 | base = nullrev | |||
|
613 | elif dp not in (p1, p2, prev): | |||
|
614 | # Pick prev when we can't be sure remote has the base revision. | |||
|
615 | base = prev | |||
|
616 | else: | |||
|
617 | base = dp | |||
|
618 | ||||
|
619 | if base != nullrev and not store.candelta(base, rev): | |||
|
620 | base = nullrev | |||
595 |
|
621 | |||
596 | revision = None |
|
622 | revision = None | |
597 | delta = None |
|
623 | delta = None | |
@@ -719,7 +745,7 b' def _revisiondeltanarrow(cl, store, isch' | |||||
719 | delta=None, |
|
745 | delta=None, | |
720 | ) |
|
746 | ) | |
721 |
|
747 | |||
722 |
def deltagroup(repo, revs, store, ischangelog, lookup, deltaparent |
|
748 | def deltagroup(repo, revs, store, ischangelog, lookup, forcedeltaparentprev, | |
723 | units=None, |
|
749 | units=None, | |
724 | ellipses=False, clrevtolocalrev=None, fullclnodes=None, |
|
750 | ellipses=False, clrevtolocalrev=None, fullclnodes=None, | |
725 | precomputedellipsis=None): |
|
751 | precomputedellipsis=None): | |
@@ -761,7 +787,7 b' def deltagroup(repo, revs, store, ischan' | |||||
761 | # corresponds to was a full changeset. |
|
787 | # corresponds to was a full changeset. | |
762 | if linknode in fullclnodes: |
|
788 | if linknode in fullclnodes: | |
763 | delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
789 | delta = _revisiondeltanormal(store, curr, prev, linknode, | |
764 |
deltaparent |
|
790 | forcedeltaparentprev) | |
765 | elif linkrev not in precomputedellipsis: |
|
791 | elif linkrev not in precomputedellipsis: | |
766 | delta = None |
|
792 | delta = None | |
767 | else: |
|
793 | else: | |
@@ -771,7 +797,7 b' def deltagroup(repo, revs, store, ischan' | |||||
771 | precomputedellipsis) |
|
797 | precomputedellipsis) | |
772 | else: |
|
798 | else: | |
773 | delta = _revisiondeltanormal(store, curr, prev, linknode, |
|
799 | delta = _revisiondeltanormal(store, curr, prev, linknode, | |
774 |
deltaparent |
|
800 | forcedeltaparentprev) | |
775 |
|
801 | |||
776 | if delta: |
|
802 | if delta: | |
777 | yield delta |
|
803 | yield delta | |
@@ -781,7 +807,8 b' def deltagroup(repo, revs, store, ischan' | |||||
781 |
|
807 | |||
782 | class cgpacker(object): |
|
808 | class cgpacker(object): | |
783 | def __init__(self, repo, filematcher, version, allowreorder, |
|
809 | def __init__(self, repo, filematcher, version, allowreorder, | |
784 |
|
|
810 | builddeltaheader, manifestsend, | |
|
811 | forcedeltaparentprev=False, | |||
785 | bundlecaps=None, ellipses=False, |
|
812 | bundlecaps=None, ellipses=False, | |
786 | shallow=False, ellipsisroots=None, fullnodes=None): |
|
813 | shallow=False, ellipsisroots=None, fullnodes=None): | |
787 | """Given a source repo, construct a bundler. |
|
814 | """Given a source repo, construct a bundler. | |
@@ -793,8 +820,9 b' class cgpacker(object):' | |||||
793 | This value is used when ``bundle.reorder`` is ``auto`` or isn't |
|
820 | This value is used when ``bundle.reorder`` is ``auto`` or isn't | |
794 | set. |
|
821 | set. | |
795 |
|
822 | |||
796 |
deltaparent |
|
823 | forcedeltaparentprev indicates whether delta parents must be against | |
797 | a specific revision. |
|
824 | the previous revision in a delta group. This should only be used for | |
|
825 | compatibility with changegroup version 1. | |||
798 |
|
826 | |||
799 | builddeltaheader is a callable that constructs the header for a group |
|
827 | builddeltaheader is a callable that constructs the header for a group | |
800 | delta. |
|
828 | delta. | |
@@ -820,7 +848,7 b' class cgpacker(object):' | |||||
820 | self._filematcher = filematcher |
|
848 | self._filematcher = filematcher | |
821 |
|
849 | |||
822 | self.version = version |
|
850 | self.version = version | |
823 |
self._deltaparent |
|
851 | self._forcedeltaparentprev = forcedeltaparentprev | |
824 | self._builddeltaheader = builddeltaheader |
|
852 | self._builddeltaheader = builddeltaheader | |
825 | self._manifestsend = manifestsend |
|
853 | self._manifestsend = manifestsend | |
826 | self._ellipses = ellipses |
|
854 | self._ellipses = ellipses | |
@@ -1025,7 +1053,7 b' class cgpacker(object):' | |||||
1025 |
|
1053 | |||
1026 | gen = deltagroup( |
|
1054 | gen = deltagroup( | |
1027 | self._repo, revs, cl, True, lookupcl, |
|
1055 | self._repo, revs, cl, True, lookupcl, | |
1028 |
self._deltaparent |
|
1056 | self._forcedeltaparentprev, | |
1029 | ellipses=self._ellipses, |
|
1057 | ellipses=self._ellipses, | |
1030 | units=_('changesets'), |
|
1058 | units=_('changesets'), | |
1031 | clrevtolocalrev={}, |
|
1059 | clrevtolocalrev={}, | |
@@ -1114,7 +1142,7 b' class cgpacker(object):' | |||||
1114 |
|
1142 | |||
1115 | deltas = deltagroup( |
|
1143 | deltas = deltagroup( | |
1116 | self._repo, revs, store, False, lookupfn, |
|
1144 | self._repo, revs, store, False, lookupfn, | |
1117 |
self._deltaparent |
|
1145 | self._forcedeltaparentprev, | |
1118 | ellipses=self._ellipses, |
|
1146 | ellipses=self._ellipses, | |
1119 | units=_('manifests'), |
|
1147 | units=_('manifests'), | |
1120 | clrevtolocalrev=clrevtolocalrev, |
|
1148 | clrevtolocalrev=clrevtolocalrev, | |
@@ -1206,7 +1234,7 b' class cgpacker(object):' | |||||
1206 |
|
1234 | |||
1207 | deltas = deltagroup( |
|
1235 | deltas = deltagroup( | |
1208 | self._repo, revs, filerevlog, False, lookupfilelog, |
|
1236 | self._repo, revs, filerevlog, False, lookupfilelog, | |
1209 |
self._deltaparent |
|
1237 | self._forcedeltaparentprev, | |
1210 | ellipses=self._ellipses, |
|
1238 | ellipses=self._ellipses, | |
1211 | clrevtolocalrev=clrevtolocalrev, |
|
1239 | clrevtolocalrev=clrevtolocalrev, | |
1212 | fullclnodes=self._fullclnodes, |
|
1240 | fullclnodes=self._fullclnodes, | |
@@ -1216,65 +1244,16 b' class cgpacker(object):' | |||||
1216 |
|
1244 | |||
1217 | progress.complete() |
|
1245 | progress.complete() | |
1218 |
|
1246 | |||
1219 | def _deltaparentprev(store, rev, p1, p2, prev): |
|
|||
1220 | """Resolve a delta parent to the previous revision. |
|
|||
1221 |
|
||||
1222 | Used for version 1 changegroups, which don't support generaldelta. |
|
|||
1223 | """ |
|
|||
1224 | return prev |
|
|||
1225 |
|
||||
1226 | def _deltaparentgeneraldelta(store, rev, p1, p2, prev): |
|
|||
1227 | """Resolve a delta parent when general deltas are supported.""" |
|
|||
1228 | dp = store.deltaparent(rev) |
|
|||
1229 | if dp == nullrev and store.storedeltachains: |
|
|||
1230 | # Avoid sending full revisions when delta parent is null. Pick prev |
|
|||
1231 | # in that case. It's tempting to pick p1 in this case, as p1 will |
|
|||
1232 | # be smaller in the common case. However, computing a delta against |
|
|||
1233 | # p1 may require resolving the raw text of p1, which could be |
|
|||
1234 | # expensive. The revlog caches should have prev cached, meaning |
|
|||
1235 | # less CPU for changegroup generation. There is likely room to add |
|
|||
1236 | # a flag and/or config option to control this behavior. |
|
|||
1237 | base = prev |
|
|||
1238 | elif dp == nullrev: |
|
|||
1239 | # revlog is configured to use full snapshot for a reason, |
|
|||
1240 | # stick to full snapshot. |
|
|||
1241 | base = nullrev |
|
|||
1242 | elif dp not in (p1, p2, prev): |
|
|||
1243 | # Pick prev when we can't be sure remote has the base revision. |
|
|||
1244 | return prev |
|
|||
1245 | else: |
|
|||
1246 | base = dp |
|
|||
1247 |
|
||||
1248 | if base != nullrev and not store.candelta(base, rev): |
|
|||
1249 | base = nullrev |
|
|||
1250 |
|
||||
1251 | return base |
|
|||
1252 |
|
||||
1253 | def _deltaparentellipses(store, rev, p1, p2, prev): |
|
|||
1254 | """Resolve a delta parent when in ellipses mode.""" |
|
|||
1255 | # TODO: send better deltas when in narrow mode. |
|
|||
1256 | # |
|
|||
1257 | # changegroup.group() loops over revisions to send, |
|
|||
1258 | # including revisions we'll skip. What this means is that |
|
|||
1259 | # `prev` will be a potentially useless delta base for all |
|
|||
1260 | # ellipsis nodes, as the client likely won't have it. In |
|
|||
1261 | # the future we should do bookkeeping about which nodes |
|
|||
1262 | # have been sent to the client, and try to be |
|
|||
1263 | # significantly smarter about delta bases. This is |
|
|||
1264 | # slightly tricky because this same code has to work for |
|
|||
1265 | # all revlogs, and we don't have the linkrev/linknode here. |
|
|||
1266 | return p1 |
|
|||
1267 |
|
||||
1268 | def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, |
|
1247 | def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, | |
1269 | shallow=False, ellipsisroots=None, fullnodes=None): |
|
1248 | shallow=False, ellipsisroots=None, fullnodes=None): | |
1270 | builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( |
|
1249 | builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( | |
1271 | d.node, d.p1node, d.p2node, d.linknode) |
|
1250 | d.node, d.p1node, d.p2node, d.linknode) | |
1272 |
|
1251 | |||
1273 | return cgpacker(repo, filematcher, b'01', |
|
1252 | return cgpacker(repo, filematcher, b'01', | |
1274 | deltaparentfn=_deltaparentprev, |
|
|||
1275 | allowreorder=None, |
|
1253 | allowreorder=None, | |
1276 | builddeltaheader=builddeltaheader, |
|
1254 | builddeltaheader=builddeltaheader, | |
1277 | manifestsend=b'', |
|
1255 | manifestsend=b'', | |
|
1256 | forcedeltaparentprev=True, | |||
1278 | bundlecaps=bundlecaps, |
|
1257 | bundlecaps=bundlecaps, | |
1279 | ellipses=ellipses, |
|
1258 | ellipses=ellipses, | |
1280 | shallow=shallow, |
|
1259 | shallow=shallow, | |
@@ -1290,7 +1269,6 b' def _makecg2packer(repo, filematcher, bu' | |||||
1290 | # generally doesn't help, so we disable it by default (treating |
|
1269 | # generally doesn't help, so we disable it by default (treating | |
1291 | # bundle.reorder=auto just like bundle.reorder=False). |
|
1270 | # bundle.reorder=auto just like bundle.reorder=False). | |
1292 | return cgpacker(repo, filematcher, b'02', |
|
1271 | return cgpacker(repo, filematcher, b'02', | |
1293 | deltaparentfn=_deltaparentgeneraldelta, |
|
|||
1294 | allowreorder=False, |
|
1272 | allowreorder=False, | |
1295 | builddeltaheader=builddeltaheader, |
|
1273 | builddeltaheader=builddeltaheader, | |
1296 | manifestsend=b'', |
|
1274 | manifestsend=b'', | |
@@ -1305,11 +1283,7 b' def _makecg3packer(repo, filematcher, bu' | |||||
1305 | builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( |
|
1283 | builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( | |
1306 | d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) |
|
1284 | d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) | |
1307 |
|
1285 | |||
1308 | deltaparentfn = (_deltaparentellipses if ellipses |
|
|||
1309 | else _deltaparentgeneraldelta) |
|
|||
1310 |
|
||||
1311 | return cgpacker(repo, filematcher, b'03', |
|
1286 | return cgpacker(repo, filematcher, b'03', | |
1312 | deltaparentfn=deltaparentfn, |
|
|||
1313 | allowreorder=False, |
|
1287 | allowreorder=False, | |
1314 | builddeltaheader=builddeltaheader, |
|
1288 | builddeltaheader=builddeltaheader, | |
1315 | manifestsend=closechunk(), |
|
1289 | manifestsend=closechunk(), |
General Comments 0
You need to be logged in to leave comments.
Login now