mercurial/changegroup.py
changeset 34091 bbdca7e460c0
parent 33712 672ad4f3bb84
child 34096 f85dfde1731a
equal deleted inserted replaced
34088:a763c891f36e 34091:bbdca7e460c0
   197 
   197 
   198         Used when you need to forward the binary stream to a file or another
   198         Used when you need to forward the binary stream to a file or another
   199         network API. To do so, it parse the changegroup data, otherwise it will
   199         network API. To do so, it parse the changegroup data, otherwise it will
   200         block in case of sshrepo because it don't know the end of the stream.
   200         block in case of sshrepo because it don't know the end of the stream.
   201         """
   201         """
   202         # an empty chunkgroup is the end of the changegroup
   202         # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
   203         # a changegroup has at least 2 chunkgroups (changelog and manifest).
   203         # and a list of filelogs. For changegroup 3, we expect 4 parts:
   204         # after that, changegroup versions 1 and 2 have a series of groups
   204         # changelog, manifestlog, a list of tree manifestlogs, and a list of
   205         # with one group per file. changegroup 3 has a series of directory
   205         # filelogs.
   206         # manifests before the files.
   206         #
   207         count = 0
   207         # Changelog and manifestlog parts are terminated with empty chunks. The
   208         emptycount = 0
   208         # tree and file parts are a list of entry sections. Each entry section
   209         while emptycount < self._grouplistcount:
   209         # is a series of chunks terminating in an empty chunk. The list of these
   210             empty = True
   210         # entry sections is terminated in yet another empty chunk, so we know
   211             count += 1
   211         # we've reached the end of the tree/file list when we reach an empty
       
   212         # chunk that was proceeded by no non-empty chunks.
       
   213 
       
   214         parts = 0
       
   215         while parts < 2 + self._grouplistcount:
       
   216             noentries = True
   212             while True:
   217             while True:
   213                 chunk = getchunk(self)
   218                 chunk = getchunk(self)
   214                 if not chunk:
   219                 if not chunk:
   215                     if empty and count > 2:
   220                     # The first two empty chunks represent the end of the
   216                         emptycount += 1
   221                     # changelog and the manifestlog portions. The remaining
       
   222                     # empty chunks represent either A) the end of individual
       
   223                     # tree or file entries in the file list, or B) the end of
       
   224                     # the entire list. It's the end of the entire list if there
       
   225                     # were no entries (i.e. noentries is True).
       
   226                     if parts < 2:
       
   227                         parts += 1
       
   228                     elif noentries:
       
   229                         parts += 1
   217                     break
   230                     break
   218                 empty = False
   231                 noentries = False
   219                 yield chunkheader(len(chunk))
   232                 yield chunkheader(len(chunk))
   220                 pos = 0
   233                 pos = 0
   221                 while pos < len(chunk):
   234                 while pos < len(chunk):
   222                     next = pos + 2**20
   235                     next = pos + 2**20
   223                     yield chunk[pos:next]
   236                     yield chunk[pos:next]