comparison mercurial/changegroup.py @ 27753:d4071cc73f46

changegroup3: add empty chunk separating directories and files Remotefilelog overrides changegroup._addchangegroupfiles(), assuming it is about files, which seems like a natural assumption. However, in changegroup3, directory manifests are sent in the files section of the changegroup. These naturally make remotefilelog unhappy. The fact that the directories are not separated from the files (although they do come before the files) also makes server.validate harder to implement. Since we read one chunk at a time from the steam, once we have found a file (non-directory) entry in the stream, we would have to push the read data back into the stream, or otherwise refactor the code. It will be easier if we add an empty chunk after all directory manifests. This change adds that empty chunk, although we don't yet take advantage of it on the reading side. We will soon move the tree manifest stuff out of _addchangegroupfiles() and into _unpackmanifests().
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 11 Jan 2016 15:10:31 -0800
parents 29cfc474c5fd
children a09f143daaf4
comparison
equal deleted inserted replaced
27752:29cfc474c5fd 27753:d4071cc73f46
504 504
505 class cg3unpacker(cg2unpacker): 505 class cg3unpacker(cg2unpacker):
506 """Unpacker for cg3 streams. 506 """Unpacker for cg3 streams.
507 507
508 cg3 streams add support for exchanging treemanifests and revlog 508 cg3 streams add support for exchanging treemanifests and revlog
509 flags, so the only changes from cg2 are the delta header and 509 flags. It adds the revlog flags to the delta header and an empty chunk
510 version number. 510 separating manifests and files.
511 """ 511 """
512 deltaheader = _CHANGEGROUPV3_DELTA_HEADER 512 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
513 deltaheadersize = struct.calcsize(deltaheader) 513 deltaheadersize = struct.calcsize(deltaheader)
514 version = '03' 514 version = '03'
515 515
907 # For now, directory headers are simply file headers with 907 # For now, directory headers are simply file headers with
908 # a trailing '/' on the path (already in the name). 908 # a trailing '/' on the path (already in the name).
909 yield self.fileheader(name) 909 yield self.fileheader(name)
910 for chunk in self.group(nodes, dirlog(name), nodes.get): 910 for chunk in self.group(nodes, dirlog(name), nodes.get):
911 yield chunk 911 yield chunk
912 yield self.close()
912 913
913 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): 914 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
914 return struct.pack( 915 return struct.pack(
915 self.deltaheader, node, p1n, p2n, basenode, linknode, flags) 916 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
916 917
917 _packermap = {'01': (cg1packer, cg1unpacker), 918 _packermap = {'01': (cg1packer, cg1unpacker),
918 # cg2 adds support for exchanging generaldelta 919 # cg2 adds support for exchanging generaldelta
919 '02': (cg2packer, cg2unpacker), 920 '02': (cg2packer, cg2unpacker),
920 # cg3 adds support for exchanging treemanifests 921 # cg3 adds support for exchanging revlog flags and treemanifests
921 '03': (cg3packer, cg3unpacker), 922 '03': (cg3packer, cg3unpacker),
922 } 923 }
923 924
924 def supportedversions(repo): 925 def supportedversions(repo):
925 versions = _packermap.keys() 926 versions = _packermap.keys()
1052 return changegroupsubset(repo, basenodes, repo.heads(), source) 1053 return changegroupsubset(repo, basenodes, repo.heads(), source)
1053 1054
1054 def _addchangegroupfiles(repo, source, revmap, trp, pr, needfiles): 1055 def _addchangegroupfiles(repo, source, revmap, trp, pr, needfiles):
1055 revisions = 0 1056 revisions = 0
1056 files = 0 1057 files = 0
1058 submfsdone = False
1057 while True: 1059 while True:
1058 chunkdata = source.filelogheader() 1060 chunkdata = source.filelogheader()
1059 if not chunkdata: 1061 if not chunkdata:
1062 if source.version == "03" and not submfsdone:
1063 submfsdone = True
1064 continue
1060 break 1065 break
1061 f = chunkdata["filename"] 1066 f = chunkdata["filename"]
1062 repo.ui.debug("adding %s revisions\n" % f) 1067 repo.ui.debug("adding %s revisions\n" % f)
1063 pr() 1068 pr()
1064 directory = (f[-1] == '/') 1069 directory = (f[-1] == '/')