Mercurial > hg-stable
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] == '/') |