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