Mercurial > public > mercurial-scm > hg
comparison mercurial/changegroup.py @ 38909:1af339c22aeb
changegroup: move fullnodes into cgpacker
And with this change, the narrow packer no longer defines
any addition attributes on packer instances!
Differential Revision: https://phab.mercurial-scm.org/D4091
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 03 Aug 2018 13:43:55 -0700 |
parents | 1469584ad5fe |
children | 245c58952298 |
comparison
equal
deleted
inserted
replaced
38908:1469584ad5fe | 38909:1af339c22aeb |
---|---|
521 | 521 |
522 class cgpacker(object): | 522 class cgpacker(object): |
523 def __init__(self, repo, filematcher, version, allowreorder, | 523 def __init__(self, repo, filematcher, version, allowreorder, |
524 useprevdelta, builddeltaheader, manifestsend, | 524 useprevdelta, builddeltaheader, manifestsend, |
525 sendtreemanifests, bundlecaps=None, ellipses=False, | 525 sendtreemanifests, bundlecaps=None, ellipses=False, |
526 shallow=False, ellipsisroots=None): | 526 shallow=False, ellipsisroots=None, fullnodes=None): |
527 """Given a source repo, construct a bundler. | 527 """Given a source repo, construct a bundler. |
528 | 528 |
529 filematcher is a matcher that matches on files to include in the | 529 filematcher is a matcher that matches on files to include in the |
530 changegroup. Used to facilitate sparse changegroups. | 530 changegroup. Used to facilitate sparse changegroups. |
531 | 531 |
550 unused in core Mercurial, extensions rely on this feature to communicate | 550 unused in core Mercurial, extensions rely on this feature to communicate |
551 capabilities to customize the changegroup packer. | 551 capabilities to customize the changegroup packer. |
552 | 552 |
553 shallow indicates whether shallow data might be sent. The packer may | 553 shallow indicates whether shallow data might be sent. The packer may |
554 need to pack file contents not introduced by the changes being packed. | 554 need to pack file contents not introduced by the changes being packed. |
555 | |
556 fullnodes is the list of nodes which should not be ellipsis nodes. We | |
557 store this rather than the set of nodes that should be ellipsis because | |
558 for very large histories we expect this to be significantly smaller. | |
555 """ | 559 """ |
556 assert filematcher | 560 assert filematcher |
557 self._filematcher = filematcher | 561 self._filematcher = filematcher |
558 | 562 |
559 self.version = version | 563 self.version = version |
566 # Set of capabilities we can use to build the bundle. | 570 # Set of capabilities we can use to build the bundle. |
567 if bundlecaps is None: | 571 if bundlecaps is None: |
568 bundlecaps = set() | 572 bundlecaps = set() |
569 self._bundlecaps = bundlecaps | 573 self._bundlecaps = bundlecaps |
570 self._isshallow = shallow | 574 self._isshallow = shallow |
575 self._fullnodes = fullnodes | |
571 | 576 |
572 # Maps ellipsis revs to their roots at the changelog level. | 577 # Maps ellipsis revs to their roots at the changelog level. |
573 self._precomputedellipsis = ellipsisroots | 578 self._precomputedellipsis = ellipsisroots |
574 | 579 |
575 # experimental config: bundle.reorder | 580 # experimental config: bundle.reorder |
742 if self._ellipses: | 747 if self._ellipses: |
743 # Only update mfs if x is going to be sent. Otherwise we | 748 # Only update mfs if x is going to be sent. Otherwise we |
744 # end up with bogus linkrevs specified for manifests and | 749 # end up with bogus linkrevs specified for manifests and |
745 # we skip some manifest nodes that we should otherwise | 750 # we skip some manifest nodes that we should otherwise |
746 # have sent. | 751 # have sent. |
747 if (x in self._full_nodes | 752 if (x in self._fullnodes |
748 or cl.rev(x) in self._precomputedellipsis): | 753 or cl.rev(x) in self._precomputedellipsis): |
749 n = c[0] | 754 n = c[0] |
750 # Record the first changeset introducing this manifest | 755 # Record the first changeset introducing this manifest |
751 # version. | 756 # version. |
752 mfs.setdefault(n, x) | 757 mfs.setdefault(n, x) |
1084 linkrev = self._clnodetorev[linknode] | 1089 linkrev = self._clnodetorev[linknode] |
1085 self._clrevtolocalrev[linkrev] = rev | 1090 self._clrevtolocalrev[linkrev] = rev |
1086 | 1091 |
1087 # This is a node to send in full, because the changeset it | 1092 # This is a node to send in full, because the changeset it |
1088 # corresponds to was a full changeset. | 1093 # corresponds to was a full changeset. |
1089 if linknode in self._full_nodes: | 1094 if linknode in self._fullnodes: |
1090 return self._revisiondeltanormal(store, rev, prev, linknode) | 1095 return self._revisiondeltanormal(store, rev, prev, linknode) |
1091 | 1096 |
1092 # At this point, a node can either be one we should skip or an | 1097 # At this point, a node can either be one we should skip or an |
1093 # ellipsis. If it's not an ellipsis, bail immediately. | 1098 # ellipsis. If it's not an ellipsis, bail immediately. |
1094 if linkrev not in self._precomputedellipsis: | 1099 if linkrev not in self._precomputedellipsis: |
1133 while walk: | 1138 while walk: |
1134 p = walk[0] | 1139 p = walk[0] |
1135 walk = walk[1:] | 1140 walk = walk[1:] |
1136 if p in self._clrevtolocalrev: | 1141 if p in self._clrevtolocalrev: |
1137 return self._clrevtolocalrev[p] | 1142 return self._clrevtolocalrev[p] |
1138 elif p in self._full_nodes: | 1143 elif p in self._fullnodes: |
1139 walk.extend([pp for pp in self._repo.changelog.parentrevs(p) | 1144 walk.extend([pp for pp in self._repo.changelog.parentrevs(p) |
1140 if pp != nullrev]) | 1145 if pp != nullrev]) |
1141 elif p in self._precomputedellipsis: | 1146 elif p in self._precomputedellipsis: |
1142 walk.extend([pp for pp in self._precomputedellipsis[p] | 1147 walk.extend([pp for pp in self._precomputedellipsis[p] |
1143 if pp != nullrev]) | 1148 if pp != nullrev]) |
1192 flags=flags, | 1197 flags=flags, |
1193 deltachunks=(diffheader, data), | 1198 deltachunks=(diffheader, data), |
1194 ) | 1199 ) |
1195 | 1200 |
1196 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, | 1201 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, |
1197 shallow=False, ellipsisroots=None): | 1202 shallow=False, ellipsisroots=None, fullnodes=None): |
1198 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( | 1203 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( |
1199 d.node, d.p1node, d.p2node, d.linknode) | 1204 d.node, d.p1node, d.p2node, d.linknode) |
1200 | 1205 |
1201 return cgpacker(repo, filematcher, b'01', | 1206 return cgpacker(repo, filematcher, b'01', |
1202 useprevdelta=True, | 1207 useprevdelta=True, |
1205 manifestsend=b'', | 1210 manifestsend=b'', |
1206 sendtreemanifests=False, | 1211 sendtreemanifests=False, |
1207 bundlecaps=bundlecaps, | 1212 bundlecaps=bundlecaps, |
1208 ellipses=ellipses, | 1213 ellipses=ellipses, |
1209 shallow=shallow, | 1214 shallow=shallow, |
1210 ellipsisroots=ellipsisroots) | 1215 ellipsisroots=ellipsisroots, |
1216 fullnodes=fullnodes) | |
1211 | 1217 |
1212 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False, | 1218 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False, |
1213 shallow=False, ellipsisroots=None): | 1219 shallow=False, ellipsisroots=None, fullnodes=None): |
1214 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( | 1220 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( |
1215 d.node, d.p1node, d.p2node, d.basenode, d.linknode) | 1221 d.node, d.p1node, d.p2node, d.basenode, d.linknode) |
1216 | 1222 |
1217 # Since generaldelta is directly supported by cg2, reordering | 1223 # Since generaldelta is directly supported by cg2, reordering |
1218 # generally doesn't help, so we disable it by default (treating | 1224 # generally doesn't help, so we disable it by default (treating |
1224 manifestsend=b'', | 1230 manifestsend=b'', |
1225 sendtreemanifests=False, | 1231 sendtreemanifests=False, |
1226 bundlecaps=bundlecaps, | 1232 bundlecaps=bundlecaps, |
1227 ellipses=ellipses, | 1233 ellipses=ellipses, |
1228 shallow=shallow, | 1234 shallow=shallow, |
1229 ellipsisroots=ellipsisroots) | 1235 ellipsisroots=ellipsisroots, |
1236 fullnodes=fullnodes) | |
1230 | 1237 |
1231 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False, | 1238 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False, |
1232 shallow=False, ellipsisroots=None): | 1239 shallow=False, ellipsisroots=None, fullnodes=None): |
1233 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( | 1240 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( |
1234 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) | 1241 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) |
1235 | 1242 |
1236 return cgpacker(repo, filematcher, b'03', | 1243 return cgpacker(repo, filematcher, b'03', |
1237 useprevdelta=False, | 1244 useprevdelta=False, |
1240 manifestsend=closechunk(), | 1247 manifestsend=closechunk(), |
1241 sendtreemanifests=True, | 1248 sendtreemanifests=True, |
1242 bundlecaps=bundlecaps, | 1249 bundlecaps=bundlecaps, |
1243 ellipses=ellipses, | 1250 ellipses=ellipses, |
1244 shallow=shallow, | 1251 shallow=shallow, |
1245 ellipsisroots=ellipsisroots) | 1252 ellipsisroots=ellipsisroots, |
1253 fullnodes=fullnodes) | |
1246 | 1254 |
1247 _packermap = {'01': (_makecg1packer, cg1unpacker), | 1255 _packermap = {'01': (_makecg1packer, cg1unpacker), |
1248 # cg2 adds support for exchanging generaldelta | 1256 # cg2 adds support for exchanging generaldelta |
1249 '02': (_makecg2packer, cg2unpacker), | 1257 '02': (_makecg2packer, cg2unpacker), |
1250 # cg3 adds support for exchanging revlog flags and treemanifests | 1258 # cg3 adds support for exchanging revlog flags and treemanifests |
1301 versions.discard('01') | 1309 versions.discard('01') |
1302 assert versions | 1310 assert versions |
1303 return min(versions) | 1311 return min(versions) |
1304 | 1312 |
1305 def getbundler(version, repo, bundlecaps=None, filematcher=None, | 1313 def getbundler(version, repo, bundlecaps=None, filematcher=None, |
1306 ellipses=False, shallow=False, ellipsisroots=None): | 1314 ellipses=False, shallow=False, ellipsisroots=None, |
1315 fullnodes=None): | |
1307 assert version in supportedoutgoingversions(repo) | 1316 assert version in supportedoutgoingversions(repo) |
1308 | 1317 |
1309 if filematcher is None: | 1318 if filematcher is None: |
1310 filematcher = matchmod.alwaysmatcher(repo.root, '') | 1319 filematcher = matchmod.alwaysmatcher(repo.root, '') |
1311 | 1320 |
1323 filematcher = matchmod.intersectmatchers(repo.narrowmatch(), | 1332 filematcher = matchmod.intersectmatchers(repo.narrowmatch(), |
1324 filematcher) | 1333 filematcher) |
1325 | 1334 |
1326 fn = _packermap[version][0] | 1335 fn = _packermap[version][0] |
1327 return fn(repo, filematcher, bundlecaps, ellipses=ellipses, | 1336 return fn(repo, filematcher, bundlecaps, ellipses=ellipses, |
1328 shallow=shallow, ellipsisroots=ellipsisroots) | 1337 shallow=shallow, ellipsisroots=ellipsisroots, |
1338 fullnodes=fullnodes) | |
1329 | 1339 |
1330 def getunbundler(version, fh, alg, extras=None): | 1340 def getunbundler(version, fh, alg, extras=None): |
1331 return _packermap[version][1](fh, alg, extras=extras) | 1341 return _packermap[version][1](fh, alg, extras=extras) |
1332 | 1342 |
1333 def _changegroupinfo(repo, nodes, source): | 1343 def _changegroupinfo(repo, nodes, source): |
1417 # sending that node's data. We override close() to detect | 1427 # sending that node's data. We override close() to detect |
1418 # pending ellipsis nodes and flush them. | 1428 # pending ellipsis nodes and flush them. |
1419 packer = getbundler(version, repo, filematcher=match, | 1429 packer = getbundler(version, repo, filematcher=match, |
1420 ellipses=True, | 1430 ellipses=True, |
1421 shallow=depth is not None, | 1431 shallow=depth is not None, |
1422 ellipsisroots=ellipsisroots) | 1432 ellipsisroots=ellipsisroots, |
1423 # Give the packer the list of nodes which should not be | 1433 fullnodes=relevant_nodes) |
1424 # ellipsis nodes. We store this rather than the set of nodes | |
1425 # that should be an ellipsis because for very large histories | |
1426 # we expect this to be significantly smaller. | |
1427 packer._full_nodes = relevant_nodes | |
1428 | 1434 |
1429 return packer.generate(common, visitnodes, False, source) | 1435 return packer.generate(common, visitnodes, False, source) |