##// END OF EJS Templates
mq: rename strip --nobackup option to --no-backup (issue2377)...
mq: rename strip --nobackup option to --no-backup (issue2377) Same option name as for hg revert --no-backup. Deprecate strip --nobackup.

File last commit:

r12044:bcc71395 default
r12282:9e457c3f default
Show More
changegroup.py
170 lines | 5.1 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # changegroup.py - Mercurial changegroup manipulation functions
#
# Copyright 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
Replace demandload with new demandimport
r3877
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Simon Heimberg
separate import lines from mercurial and general python modules
r8312 import util
import struct, os, bz2, zlib, tempfile
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
def getchunk(source):
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """return the next chunk from changegroup 'source' as a string"""
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 d = source.read(4)
if not d:
return ""
l = struct.unpack(">l", d)[0]
if l <= 4:
return ""
d = source.read(l - 4)
if len(d) < l - 4:
raise util.Abort(_("premature EOF reading chunk"
" (got %d bytes, expected %d)")
% (len(d), l - 4))
return d
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 def chunkiter(source, progress=None):
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """iterate through the chunks in source, yielding a sequence of chunks
(strings)"""
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 while 1:
c = getchunk(source)
if not c:
break
Augie Fackler
localrepo: show indeterminate progress for incoming data...
r10430 elif progress is not None:
progress()
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 yield c
Matt Mackall
changegroup: avoid large copies...
r5368 def chunkheader(length):
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """return a changegroup chunk header (string)"""
Matt Mackall
changegroup: avoid large copies...
r5368 return struct.pack(">l", length + 4)
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981
def closechunk():
Greg Ward
Improve some docstrings relating to changegroups and prepush().
r9437 """return a changegroup chunk header (string) for a zero-length chunk"""
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 return struct.pack(">l", 0)
Matt Mackall
move write_bundle to changegroup.py
r3659 class nocompress(object):
def compress(self, x):
return x
def flush(self):
return ""
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 bundletypes = {
Benoit Boissinot
fix writebundle for bz2 bundles
r3704 "": ("", nocompress),
"HG10UN": ("HG10UN", nocompress),
Alexis S. L. Carvalho
changegroup.py: delay the loading of the bz2 and zlib modules
r3762 "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
"HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 }
Dirkjan Ochtman
localrepo: unify changegroup and changegroupsubset code paths a bit
r10356 def collector(cl, mmfs, files):
# Gather information about changeset nodes going out in a bundle.
# We want to gather manifests needed and filelogs affected.
def collect(node):
c = cl.read(node)
Benoit Boissinot
changegroup*(): use set instead of dict
r11648 files.update(c[3])
Dirkjan Ochtman
localrepo: unify changegroup and changegroupsubset code paths a bit
r10356 mmfs.setdefault(c[0], node)
return collect
Martin Geisler
typos: "it's" -> "its"
r9087 # hgweb uses this list to communicate its preferred type
Dirkjan Ochtman
hgweb: use bundletypes from mercurial.changegroup
r6152 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
Thomas Arendsen Hein
Use 'bundletype' instead of 'type' to not shadow built-in function.
r3706 def writebundle(cg, filename, bundletype):
Matt Mackall
move write_bundle to changegroup.py
r3659 """Write a bundle file and return its filename.
Existing files will not be overwritten.
If no filename is specified, a temporary file is created.
bz2 compression can be turned off.
The bundle file will be deleted in case of errors.
"""
fh = None
cleanup = None
try:
if filename:
fh = open(filename, "wb")
else:
fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
fh = os.fdopen(fd, "wb")
cleanup = filename
Thomas Arendsen Hein
Use 'bundletype' instead of 'type' to not shadow built-in function.
r3706 header, compressor = bundletypes[bundletype]
Benoit Boissinot
fix writebundle for bz2 bundles
r3704 fh.write(header)
z = compressor()
Matt Mackall
unduplicate bundle writing code from httprepo
r3662
Matt Mackall
move write_bundle to changegroup.py
r3659 # parse the changegroup data, otherwise we will block
# in case of sshrepo because we don't know the end of the stream
# an empty chunkiter is the end of the changegroup
Alexis S. L. Carvalho
allow the creation of bundles with empty changelog/manifest chunks
r5906 # a changegroup has at least 2 chunkiters (changelog and manifest).
# after that, an empty chunkiter is the end of the changegroup
Matt Mackall
move write_bundle to changegroup.py
r3659 empty = False
Alexis S. L. Carvalho
allow the creation of bundles with empty changelog/manifest chunks
r5906 count = 0
while not empty or count <= 2:
Matt Mackall
move write_bundle to changegroup.py
r3659 empty = True
Alexis S. L. Carvalho
allow the creation of bundles with empty changelog/manifest chunks
r5906 count += 1
Matt Mackall
move write_bundle to changegroup.py
r3659 for chunk in chunkiter(cg):
empty = False
Matt Mackall
changegroup: avoid large copies...
r5368 fh.write(z.compress(chunkheader(len(chunk))))
pos = 0
while pos < len(chunk):
next = pos + 2**20
fh.write(z.compress(chunk[pos:next]))
pos = next
Matt Mackall
move write_bundle to changegroup.py
r3659 fh.write(z.compress(closechunk()))
fh.write(z.flush())
cleanup = None
return filename
finally:
if fh is not None:
fh.close()
if cleanup is not None:
os.unlink(cleanup)
Matt Mackall
create a readbundle function
r3660
Matt Mackall
bundle: factor out decompressor
r12041 def decompressor(fh, alg):
if alg == 'UN':
Dirkjan Ochtman
improve changegroup.readbundle(), use it in hgweb
r6154 return fh
Matt Mackall
bundle: factor out decompressor
r12041 elif alg == 'GZ':
Dirkjan Ochtman
improve changegroup.readbundle(), use it in hgweb
r6154 def generator(f):
zd = zlib.decompressobj()
for chunk in f:
yield zd.decompress(chunk)
Matt Mackall
bundle: factor out decompressor
r12041 elif alg == 'BZ':
Matt Mackall
create a readbundle function
r3660 def generator(f):
zd = bz2.BZ2Decompressor()
zd.decompress("BZ")
for chunk in util.filechunkiter(f, 4096):
yield zd.decompress(chunk)
Matt Mackall
bundle: factor out decompressor
r12041 else:
raise util.Abort("unknown bundle compression '%s'" % alg)
return generator(fh)
Matt Mackall
bundle: introduce bundle class
r12043 class unbundle10(object):
def __init__(self, fh, alg):
self._stream = util.chunkbuffer(decompressor(fh, alg))
Matt Mackall
bundlerepo: remove duplication of bundle decompressors
r12044 self._type = alg
def compressed(self):
return self._type != 'UN'
Matt Mackall
bundle: introduce bundle class
r12043 def read(self, l):
return self._stream.read(l)
Dirkjan Ochtman
improve changegroup.readbundle(), use it in hgweb
r6154 def readbundle(fh, fname):
header = fh.read(6)
Matt Mackall
bundle: unify/refactor unbundle/readbundle
r12042
if not fname:
fname = "stream"
if not header.startswith('HG') and header.startswith('\0'):
# headerless bundle, clean things up
def fixup(f, h):
yield h
for x in f:
yield x
fh = fixup(fh, header)
header = "HG10UN"
magic, version, alg = header[0:2], header[2:4], header[4:6]
if magic != 'HG':
raise util.Abort(_('%s: not a Mercurial bundle') % fname)
if version != '10':
raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
Matt Mackall
bundle: introduce bundle class
r12043 return unbundle10(fh, alg)