mercurial/changegroup.py
changeset 3666 025f68f22ae2
parent 2470 fe1689273f84
child 3667 8500a13ec44b
equal deleted inserted replaced
3665:d12c8668b102 3666:025f68f22ae2
     6 This software may be used and distributed according to the terms
     6 This software may be used and distributed according to the terms
     7 of the GNU General Public License, incorporated herein by reference.
     7 of the GNU General Public License, incorporated herein by reference.
     8 """
     8 """
     9 from i18n import gettext as _
     9 from i18n import gettext as _
    10 from demandload import *
    10 from demandload import *
    11 demandload(globals(), "struct util")
    11 demandload(globals(), "struct os bz2 util tempfile")
    12 
    12 
    13 def getchunk(source):
    13 def getchunk(source):
    14     """get a chunk from a changegroup"""
    14     """get a chunk from a changegroup"""
    15     d = source.read(4)
    15     d = source.read(4)
    16     if not d:
    16     if not d:
    39     return "%s%s" % (header, data)
    39     return "%s%s" % (header, data)
    40 
    40 
    41 def closechunk():
    41 def closechunk():
    42     return struct.pack(">l", 0)
    42     return struct.pack(">l", 0)
    43 
    43 
       
    44 class nocompress(object):
       
    45     def compress(self, x):
       
    46         return x
       
    47     def flush(self):
       
    48         return ""
       
    49 
       
    50 def writebundle(cg, filename, compress):
       
    51     """Write a bundle file and return its filename.
       
    52 
       
    53     Existing files will not be overwritten.
       
    54     If no filename is specified, a temporary file is created.
       
    55     bz2 compression can be turned off.
       
    56     The bundle file will be deleted in case of errors.
       
    57     """
       
    58 
       
    59     fh = None
       
    60     cleanup = None
       
    61     try:
       
    62         if filename:
       
    63             if os.path.exists(filename):
       
    64                 raise util.Abort(_("file '%s' already exists") % filename)
       
    65             fh = open(filename, "wb")
       
    66         else:
       
    67             fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
       
    68             fh = os.fdopen(fd, "wb")
       
    69         cleanup = filename
       
    70 
       
    71         if compress:
       
    72             fh.write("HG10")
       
    73             z = bz2.BZ2Compressor(9)
       
    74         else:
       
    75             fh.write("HG10UN")
       
    76             z = nocompress()
       
    77         # parse the changegroup data, otherwise we will block
       
    78         # in case of sshrepo because we don't know the end of the stream
       
    79 
       
    80         # an empty chunkiter is the end of the changegroup
       
    81         empty = False
       
    82         while not empty:
       
    83             empty = True
       
    84             for chunk in chunkiter(cg):
       
    85                 empty = False
       
    86                 fh.write(z.compress(genchunk(chunk)))
       
    87             fh.write(z.compress(closechunk()))
       
    88         fh.write(z.flush())
       
    89         cleanup = None
       
    90         return filename
       
    91     finally:
       
    92         if fh is not None:
       
    93             fh.close()
       
    94         if cleanup is not None:
       
    95             os.unlink(cleanup)