mercurial/changegroup.py
changeset 26266 1e042e31bd0c
parent 25921 74b303a637bc
child 26267 eca468b8fae4
equal deleted inserted replaced
26265:077f20eed4b2 26266:1e042e31bd0c
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 import bz2
       
    11 import os
    10 import os
    12 import struct
    11 import struct
    13 import tempfile
    12 import tempfile
    14 import weakref
    13 import weakref
    15 import zlib
       
    16 
    14 
    17 from .i18n import _
    15 from .i18n import _
    18 from .node import (
    16 from .node import (
    19     hex,
    17     hex,
    20     nullid,
    18     nullid,
    79         result = 1 + changedheads
    77         result = 1 + changedheads
    80     elif changedheads < 0:
    78     elif changedheads < 0:
    81         result = -1 + changedheads
    79         result = -1 + changedheads
    82     return result
    80     return result
    83 
    81 
    84 class nocompress(object):
       
    85     def compress(self, x):
       
    86         return x
       
    87     def flush(self):
       
    88         return ""
       
    89 
       
    90 bundletypes = {
    82 bundletypes = {
    91     "": ("", nocompress), # only when using unbundle on ssh and old http servers
    83     "": ("", 'UN'),       # only when using unbundle on ssh and old http servers
    92                           # since the unification ssh accepts a header but there
    84                           # since the unification ssh accepts a header but there
    93                           # is no capability signaling it.
    85                           # is no capability signaling it.
    94     "HG20": (), # special-cased below
    86     "HG20": (), # special-cased below
    95     "HG10UN": ("HG10UN", nocompress),
    87     "HG10UN": ("HG10UN", 'UN'),
    96     "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
    88     "HG10BZ": ("HG10", 'BZ'),
    97     "HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
    89     "HG10GZ": ("HG10GZ", 'GZ'),
    98 }
    90 }
    99 
    91 
   100 # hgweb uses this list to communicate its preferred type
    92 # hgweb uses this list to communicate its preferred type
   101 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
    93 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
   102 
    94 
   125         if bundletype == "HG20":
   117         if bundletype == "HG20":
   126             from . import bundle2
   118             from . import bundle2
   127             bundle = bundle2.bundle20(ui)
   119             bundle = bundle2.bundle20(ui)
   128             part = bundle.newpart('changegroup', data=cg.getchunks())
   120             part = bundle.newpart('changegroup', data=cg.getchunks())
   129             part.addparam('version', cg.version)
   121             part.addparam('version', cg.version)
   130             z = nocompress()
   122             z = util.compressors['UN']()
   131             chunkiter = bundle.getchunks()
   123             chunkiter = bundle.getchunks()
   132         else:
   124         else:
   133             if cg.version != '01':
   125             if cg.version != '01':
   134                 raise util.Abort(_('old bundle types only supports v1 '
   126                 raise util.Abort(_('old bundle types only supports v1 '
   135                                    'changegroups'))
   127                                    'changegroups'))
   136             header, compressor = bundletypes[bundletype]
   128             header, comp = bundletypes[bundletype]
   137             fh.write(header)
   129             fh.write(header)
   138             z = compressor()
   130             if comp not in util.compressors:
       
   131                 raise util.Abort(_('unknown stream compression type: %s')
       
   132                                  % comp)
       
   133             z = util.compressors[comp]()
   139             chunkiter = cg.getchunks()
   134             chunkiter = cg.getchunks()
   140 
   135 
   141         # parse the changegroup data, otherwise we will block
   136         # parse the changegroup data, otherwise we will block
   142         # in case of sshrepo because we don't know the end of the stream
   137         # in case of sshrepo because we don't know the end of the stream
   143 
   138 
   156             if filename and vfs:
   151             if filename and vfs:
   157                 vfs.unlink(cleanup)
   152                 vfs.unlink(cleanup)
   158             else:
   153             else:
   159                 os.unlink(cleanup)
   154                 os.unlink(cleanup)
   160 
   155 
   161 def decompressor(fh, alg):
       
   162     if alg == 'UN':
       
   163         return fh
       
   164     elif alg == 'GZ':
       
   165         def generator(f):
       
   166             zd = zlib.decompressobj()
       
   167             for chunk in util.filechunkiter(f):
       
   168                 yield zd.decompress(chunk)
       
   169     elif alg == 'BZ':
       
   170         def generator(f):
       
   171             zd = bz2.BZ2Decompressor()
       
   172             zd.decompress("BZ")
       
   173             for chunk in util.filechunkiter(f, 4096):
       
   174                 yield zd.decompress(chunk)
       
   175     else:
       
   176         raise util.Abort("unknown bundle compression '%s'" % alg)
       
   177     return util.chunkbuffer(generator(fh))
       
   178 
       
   179 class cg1unpacker(object):
   156 class cg1unpacker(object):
   180     deltaheader = _CHANGEGROUPV1_DELTA_HEADER
   157     deltaheader = _CHANGEGROUPV1_DELTA_HEADER
   181     deltaheadersize = struct.calcsize(deltaheader)
   158     deltaheadersize = struct.calcsize(deltaheader)
   182     version = '01'
   159     version = '01'
   183     def __init__(self, fh, alg):
   160     def __init__(self, fh, alg):
   184         self._stream = decompressor(fh, alg)
   161         if not alg in util.decompressors:
       
   162             raise util.Abort(_('unknown stream compression type: %s')
       
   163                              % alg)
       
   164         self._stream = util.decompressors[alg](fh)
   185         self._type = alg
   165         self._type = alg
   186         self.callback = None
   166         self.callback = None
   187     def compressed(self):
   167     def compressed(self):
   188         return self._type != 'UN'
   168         return self._type != 'UN'
   189     def read(self, l):
   169     def read(self, l):