Show More
@@ -522,8 +522,8 b' class revisiondelta(object):' | |||
|
522 | 522 | class cgpacker(object): |
|
523 | 523 | def __init__(self, repo, filematcher, version, allowreorder, |
|
524 | 524 | useprevdelta, builddeltaheader, manifestsend, |
|
525 |
sendtreemanifests, bundlecaps=None, |
|
|
526 | ellipsisroots=None): | |
|
525 | sendtreemanifests, bundlecaps=None, ellipses=False, | |
|
526 | shallow=False, ellipsisroots=None): | |
|
527 | 527 | """Given a source repo, construct a bundler. |
|
528 | 528 | |
|
529 | 529 | filematcher is a matcher that matches on files to include in the |
@@ -543,6 +543,8 b' class cgpacker(object):' | |||
|
543 | 543 | |
|
544 | 544 | sendtreemanifests indicates whether tree manifests should be emitted. |
|
545 | 545 | |
|
546 | ellipses indicates whether ellipsis serving mode is enabled. | |
|
547 | ||
|
546 | 548 | bundlecaps is optional and can be used to specify the set of |
|
547 | 549 | capabilities which can be used to build the bundle. While bundlecaps is |
|
548 | 550 | unused in core Mercurial, extensions rely on this feature to communicate |
@@ -559,6 +561,7 b' class cgpacker(object):' | |||
|
559 | 561 | self._builddeltaheader = builddeltaheader |
|
560 | 562 | self._manifestsend = manifestsend |
|
561 | 563 | self._sendtreemanifests = sendtreemanifests |
|
564 | self._ellipses = ellipses | |
|
562 | 565 | |
|
563 | 566 | # Set of capabilities we can use to build the bundle. |
|
564 | 567 | if bundlecaps is None: |
@@ -628,7 +631,7 b' class cgpacker(object):' | |||
|
628 | 631 | # order that they're introduced in dramatis personae by the |
|
629 | 632 | # changelog, so what we do is we sort the non-changelog histories |
|
630 | 633 | # by the order in which they are used by the changelog. |
|
631 |
if |
|
|
634 | if self._ellipses and self._clnodetorev: | |
|
632 | 635 | key = lambda n: self._clnodetorev[lookup(n)] |
|
633 | 636 | return [store.rev(n) for n in sorted(nodelist, key=key)] |
|
634 | 637 | |
@@ -729,8 +732,6 b' class cgpacker(object):' | |||
|
729 | 732 | mfrevlog = mfl._revlog |
|
730 | 733 | changedfiles = set() |
|
731 | 734 | |
|
732 | ellipsesmode = util.safehasattr(self, '_full_nodes') | |
|
733 | ||
|
734 | 735 | # Callback for the changelog, used to collect changed files and |
|
735 | 736 | # manifest nodes. |
|
736 | 737 | # Returns the linkrev node (identity in the changelog case). |
@@ -738,7 +739,7 b' class cgpacker(object):' | |||
|
738 | 739 | c = cl.read(x) |
|
739 | 740 | clrevorder[x] = len(clrevorder) |
|
740 | 741 | |
|
741 |
if ellipses |
|
|
742 | if self._ellipses: | |
|
742 | 743 | # Only update mfs if x is going to be sent. Otherwise we |
|
743 | 744 | # end up with bogus linkrevs specified for manifests and |
|
744 | 745 | # we skip some manifest nodes that we should otherwise |
@@ -805,7 +806,7 b' class cgpacker(object):' | |||
|
805 | 806 | fastpathlinkrev, mfs, fnodes, source): |
|
806 | 807 | yield chunk |
|
807 | 808 | |
|
808 |
if ellipses |
|
|
809 | if self._ellipses: | |
|
809 | 810 | mfdicts = None |
|
810 | 811 | if self._isshallow: |
|
811 | 812 | mfdicts = [(self._repo.manifestlog[n].read(), lr) |
@@ -825,7 +826,7 b' class cgpacker(object):' | |||
|
825 | 826 | revs = ((r, llr(r)) for r in filerevlog) |
|
826 | 827 | return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs) |
|
827 | 828 | |
|
828 |
if ellipses |
|
|
829 | if self._ellipses: | |
|
829 | 830 | # We need to pass the mfdicts variable down into |
|
830 | 831 | # generatefiles(), but more than one command might have |
|
831 | 832 | # wrapped generatefiles so we can't modify the function |
@@ -982,7 +983,7 b' class cgpacker(object):' | |||
|
982 | 983 | return prev |
|
983 | 984 | |
|
984 | 985 | # Narrow ellipses mode. |
|
985 | if util.safehasattr(self, '_full_nodes'): | |
|
986 | if self._ellipses: | |
|
986 | 987 | # TODO: send better deltas when in narrow mode. |
|
987 | 988 | # |
|
988 | 989 | # changegroup.group() loops over revisions to send, |
@@ -1022,7 +1023,7 b' class cgpacker(object):' | |||
|
1022 | 1023 | return base |
|
1023 | 1024 | |
|
1024 | 1025 | def _revchunk(self, store, rev, prev, linknode): |
|
1025 | if util.safehasattr(self, '_full_nodes'): | |
|
1026 | if self._ellipses: | |
|
1026 | 1027 | fn = self._revisiondeltanarrow |
|
1027 | 1028 | else: |
|
1028 | 1029 | fn = self._revisiondeltanormal |
@@ -1192,8 +1193,8 b' class cgpacker(object):' | |||
|
1192 | 1193 | deltachunks=(diffheader, data), |
|
1193 | 1194 | ) |
|
1194 | 1195 | |
|
1195 |
def _makecg1packer(repo, filematcher, bundlecaps, |
|
|
1196 | ellipsisroots=None): | |
|
1196 | def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, | |
|
1197 | shallow=False, ellipsisroots=None): | |
|
1197 | 1198 | builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( |
|
1198 | 1199 | d.node, d.p1node, d.p2node, d.linknode) |
|
1199 | 1200 | |
@@ -1204,11 +1205,12 b' def _makecg1packer(repo, filematcher, bu' | |||
|
1204 | 1205 | manifestsend=b'', |
|
1205 | 1206 | sendtreemanifests=False, |
|
1206 | 1207 | bundlecaps=bundlecaps, |
|
1208 | ellipses=ellipses, | |
|
1207 | 1209 | shallow=shallow, |
|
1208 | 1210 | ellipsisroots=ellipsisroots) |
|
1209 | 1211 | |
|
1210 |
def _makecg2packer(repo, filematcher, bundlecaps, |
|
|
1211 | ellipsisroots=None): | |
|
1212 | def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False, | |
|
1213 | shallow=False, ellipsisroots=None): | |
|
1212 | 1214 | builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( |
|
1213 | 1215 | d.node, d.p1node, d.p2node, d.basenode, d.linknode) |
|
1214 | 1216 | |
@@ -1222,11 +1224,12 b' def _makecg2packer(repo, filematcher, bu' | |||
|
1222 | 1224 | manifestsend=b'', |
|
1223 | 1225 | sendtreemanifests=False, |
|
1224 | 1226 | bundlecaps=bundlecaps, |
|
1227 | ellipses=ellipses, | |
|
1225 | 1228 | shallow=shallow, |
|
1226 | 1229 | ellipsisroots=ellipsisroots) |
|
1227 | 1230 | |
|
1228 |
def _makecg3packer(repo, filematcher, bundlecaps, |
|
|
1229 | ellipsisroots=None): | |
|
1231 | def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False, | |
|
1232 | shallow=False, ellipsisroots=None): | |
|
1230 | 1233 | builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( |
|
1231 | 1234 | d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) |
|
1232 | 1235 | |
@@ -1237,6 +1240,7 b' def _makecg3packer(repo, filematcher, bu' | |||
|
1237 | 1240 | manifestsend=closechunk(), |
|
1238 | 1241 | sendtreemanifests=True, |
|
1239 | 1242 | bundlecaps=bundlecaps, |
|
1243 | ellipses=ellipses, | |
|
1240 | 1244 | shallow=shallow, |
|
1241 | 1245 | ellipsisroots=ellipsisroots) |
|
1242 | 1246 | |
@@ -1299,7 +1303,7 b' def safeversion(repo):' | |||
|
1299 | 1303 | return min(versions) |
|
1300 | 1304 | |
|
1301 | 1305 | def getbundler(version, repo, bundlecaps=None, filematcher=None, |
|
1302 | shallow=False, ellipsisroots=None): | |
|
1306 | ellipses=False, shallow=False, ellipsisroots=None): | |
|
1303 | 1307 | assert version in supportedoutgoingversions(repo) |
|
1304 | 1308 | |
|
1305 | 1309 | if filematcher is None: |
@@ -1309,14 +1313,19 b' def getbundler(version, repo, bundlecaps' | |||
|
1309 | 1313 | raise error.ProgrammingError('version 01 changegroups do not support ' |
|
1310 | 1314 | 'sparse file matchers') |
|
1311 | 1315 | |
|
1316 | if ellipses and version in (b'01', b'02'): | |
|
1317 | raise error.Abort( | |
|
1318 | _('ellipsis nodes require at least cg3 on client and server, ' | |
|
1319 | 'but negotiated version %s') % version) | |
|
1320 | ||
|
1312 | 1321 | # Requested files could include files not in the local store. So |
|
1313 | 1322 | # filter those out. |
|
1314 | 1323 | filematcher = matchmod.intersectmatchers(repo.narrowmatch(), |
|
1315 | 1324 | filematcher) |
|
1316 | 1325 | |
|
1317 | 1326 | fn = _packermap[version][0] |
|
1318 |
return fn(repo, filematcher, bundlecaps, |
|
|
1319 | ellipsisroots=ellipsisroots) | |
|
1327 | return fn(repo, filematcher, bundlecaps, ellipses=ellipses, | |
|
1328 | shallow=shallow, ellipsisroots=ellipsisroots) | |
|
1320 | 1329 | |
|
1321 | 1330 | def getunbundler(version, fh, alg, extras=None): |
|
1322 | 1331 | return _packermap[version][1](fh, alg, extras=extras) |
@@ -1402,16 +1411,13 b' def _addchangegroupfiles(repo, source, r' | |||
|
1402 | 1411 | |
|
1403 | 1412 | def _packellipsischangegroup(repo, common, match, relevant_nodes, |
|
1404 | 1413 | ellipsisroots, visitnodes, depth, source, version): |
|
1405 | if version in ('01', '02'): | |
|
1406 | raise error.Abort( | |
|
1407 | 'ellipsis nodes require at least cg3 on client and server, ' | |
|
1408 | 'but negotiated version %s' % version) | |
|
1409 | 1414 | # We wrap cg1packer.revchunk, using a side channel to pass |
|
1410 | 1415 | # relevant_nodes into that area. Then if linknode isn't in the |
|
1411 | 1416 | # set, we know we have an ellipsis node and we should defer |
|
1412 | 1417 | # sending that node's data. We override close() to detect |
|
1413 | 1418 | # pending ellipsis nodes and flush them. |
|
1414 | 1419 | packer = getbundler(version, repo, filematcher=match, |
|
1420 | ellipses=True, | |
|
1415 | 1421 | shallow=depth is not None, |
|
1416 | 1422 | ellipsisroots=ellipsisroots) |
|
1417 | 1423 | # Give the packer the list of nodes which should not be |
General Comments 0
You need to be logged in to leave comments.
Login now