comparison mercurial/changegroup.py @ 38925:8a13855c8dbe

changegroup: always use the treemanifest-enabled version of _packmanifests() It works for flat manifests too. We just cannot use cg1 or cg2 if we have subdirectory manifests. Differential Revision: https://phab.mercurial-scm.org/D4124
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 06 Aug 2018 00:33:15 -0700
parents 245c58952298
children 9134c4e46084
comparison
equal deleted inserted replaced
38924:6fed8b323651 38925:8a13855c8dbe
520 deltachunks = attr.ib() 520 deltachunks = attr.ib()
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 bundlecaps=None, ellipses=False,
526 shallow=False, ellipsisroots=None, fullnodes=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.
538 538
539 builddeltaheader is a callable that constructs the header for a group 539 builddeltaheader is a callable that constructs the header for a group
540 delta. 540 delta.
541 541
542 manifestsend is a chunk to send after manifests have been fully emitted. 542 manifestsend is a chunk to send after manifests have been fully emitted.
543
544 sendtreemanifests indicates whether tree manifests should be emitted.
545 543
546 ellipses indicates whether ellipsis serving mode is enabled. 544 ellipses indicates whether ellipsis serving mode is enabled.
547 545
548 bundlecaps is optional and can be used to specify the set of 546 bundlecaps is optional and can be used to specify the set of
549 capabilities which can be used to build the bundle. While bundlecaps is 547 capabilities which can be used to build the bundle. While bundlecaps is
562 560
563 self.version = version 561 self.version = version
564 self._useprevdelta = useprevdelta 562 self._useprevdelta = useprevdelta
565 self._builddeltaheader = builddeltaheader 563 self._builddeltaheader = builddeltaheader
566 self._manifestsend = manifestsend 564 self._manifestsend = manifestsend
567 self._sendtreemanifests = sendtreemanifests
568 self._ellipses = ellipses 565 self._ellipses = ellipses
569 566
570 # Set of capabilities we can use to build the bundle. 567 # Set of capabilities we can use to build the bundle.
571 if bundlecaps is None: 568 if bundlecaps is None:
572 bundlecaps = set() 569 bundlecaps = set()
699 696
700 rr, rl = store.rev, store.linkrev 697 rr, rl = store.rev, store.linkrev
701 return [n for n in missing if rl(rr(n)) not in commonrevs] 698 return [n for n in missing if rl(rr(n)) not in commonrevs]
702 699
703 def _packmanifests(self, dir, mfnodes, lookuplinknode): 700 def _packmanifests(self, dir, mfnodes, lookuplinknode):
704 """Pack flat manifests into a changegroup stream.""" 701 """Pack manifests into a changegroup stream.
705 assert not dir
706 for chunk in self.group(mfnodes, self._repo.manifestlog._revlog,
707 lookuplinknode, units=_('manifests')):
708 yield chunk
709
710 def _packtreemanifests(self, dir, mfnodes, lookuplinknode):
711 """Version of _packmanifests that operates on directory manifests.
712 702
713 Encodes the directory name in the output so multiple manifests 703 Encodes the directory name in the output so multiple manifests
714 can be sent. 704 can be sent. Multiple manifests is not supported by cg1 and cg2.
715 """ 705 """
716 assert self.version == b'03'
717 706
718 if dir: 707 if dir:
708 assert self.version == b'03'
719 yield self._fileheader(dir) 709 yield self._fileheader(dir)
720 710
721 # TODO violates storage abstractions by assuming revlogs. 711 # TODO violates storage abstractions by assuming revlogs.
722 dirlog = self._repo.manifestlog._revlog.dirlog(dir) 712 dirlog = self._repo.manifestlog._revlog.dirlog(dir)
723 for chunk in self.group(mfnodes, dirlog, lookuplinknode, 713 for chunk in self.group(mfnodes, dirlog, lookuplinknode,
900 if clrevorder[clnode] < clrevorder[fclnode]: 890 if clrevorder[clnode] < clrevorder[fclnode]:
901 fclnodes[n] = clnode 891 fclnodes[n] = clnode
902 return clnode 892 return clnode
903 return lookupmflinknode 893 return lookupmflinknode
904 894
905 fn = (self._packtreemanifests if self._sendtreemanifests
906 else self._packmanifests)
907 size = 0 895 size = 0
908 while tmfnodes: 896 while tmfnodes:
909 dir, nodes = tmfnodes.popitem() 897 dir, nodes = tmfnodes.popitem()
910 prunednodes = self._prune(dirlog(dir), nodes, commonrevs) 898 prunednodes = self._prune(dirlog(dir), nodes, commonrevs)
911 if not dir or prunednodes: 899 if not dir or prunednodes:
912 for x in fn(dir, prunednodes, makelookupmflinknode(dir, nodes)): 900 for x in self._packmanifests(dir, prunednodes,
901 makelookupmflinknode(dir, nodes)):
913 size += len(x) 902 size += len(x)
914 yield x 903 yield x
915 self._verbosenote(_('%8.i (manifests)\n') % size) 904 self._verbosenote(_('%8.i (manifests)\n') % size)
916 yield self._manifestsend 905 yield self._manifestsend
917 906
1206 return cgpacker(repo, filematcher, b'01', 1195 return cgpacker(repo, filematcher, b'01',
1207 useprevdelta=True, 1196 useprevdelta=True,
1208 allowreorder=None, 1197 allowreorder=None,
1209 builddeltaheader=builddeltaheader, 1198 builddeltaheader=builddeltaheader,
1210 manifestsend=b'', 1199 manifestsend=b'',
1211 sendtreemanifests=False,
1212 bundlecaps=bundlecaps, 1200 bundlecaps=bundlecaps,
1213 ellipses=ellipses, 1201 ellipses=ellipses,
1214 shallow=shallow, 1202 shallow=shallow,
1215 ellipsisroots=ellipsisroots, 1203 ellipsisroots=ellipsisroots,
1216 fullnodes=fullnodes) 1204 fullnodes=fullnodes)
1226 return cgpacker(repo, filematcher, b'02', 1214 return cgpacker(repo, filematcher, b'02',
1227 useprevdelta=False, 1215 useprevdelta=False,
1228 allowreorder=False, 1216 allowreorder=False,
1229 builddeltaheader=builddeltaheader, 1217 builddeltaheader=builddeltaheader,
1230 manifestsend=b'', 1218 manifestsend=b'',
1231 sendtreemanifests=False,
1232 bundlecaps=bundlecaps, 1219 bundlecaps=bundlecaps,
1233 ellipses=ellipses, 1220 ellipses=ellipses,
1234 shallow=shallow, 1221 shallow=shallow,
1235 ellipsisroots=ellipsisroots, 1222 ellipsisroots=ellipsisroots,
1236 fullnodes=fullnodes) 1223 fullnodes=fullnodes)
1243 return cgpacker(repo, filematcher, b'03', 1230 return cgpacker(repo, filematcher, b'03',
1244 useprevdelta=False, 1231 useprevdelta=False,
1245 allowreorder=False, 1232 allowreorder=False,
1246 builddeltaheader=builddeltaheader, 1233 builddeltaheader=builddeltaheader,
1247 manifestsend=closechunk(), 1234 manifestsend=closechunk(),
1248 sendtreemanifests=True,
1249 bundlecaps=bundlecaps, 1235 bundlecaps=bundlecaps,
1250 ellipses=ellipses, 1236 ellipses=ellipses,
1251 shallow=shallow, 1237 shallow=shallow,
1252 ellipsisroots=ellipsisroots, 1238 ellipsisroots=ellipsisroots,
1253 fullnodes=fullnodes) 1239 fullnodes=fullnodes)