annotate mercurial/changegroup.py @ 13579:3cbb3c57a50e

transplant: added 'HGREVISION' variable to the environment passed to the 'filter' command Sometimes it is necessary to know the original revision ID in order to correctly rewrite the patch or commit message when transplanting. This patch follows the pattern set by the existing 'HGUSER' environment variable, and adds a test that covers both HGUSER and HGREVISION.
author Luke Plant <L.Plant.98@cantab.net>
date Fri, 11 Mar 2011 15:48:44 +0000
parents acbe171c8fbe
children 4ed718f909e5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
1 # changegroup.py - Mercurial changegroup manipulation functions
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
2 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
4 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9437
diff changeset
6 # GNU General Public License version 2 or any later version.
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3859
diff changeset
7
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
8 from i18n import _
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8226
diff changeset
9 import util
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8226
diff changeset
10 import struct, os, bz2, zlib, tempfile
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
11
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
12 def readexactly(stream, n):
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
13 '''read n bytes from stream.read and abort if less was available'''
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
14 s = stream.read(n)
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
15 if len(s) < n:
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
16 raise util.Abort(_("stream ended unexpectedly"
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
17 " (got %d bytes, expected %d)")
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
18 % (len(s), n))
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
19 return s
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
20
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
21 def getchunk(stream):
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
22 """return the next chunk from stream as a string"""
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
23 d = readexactly(stream, 4)
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
24 l = struct.unpack(">l", d)[0]
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
25 if l <= 4:
13458
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
26 if l:
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
27 raise util.Abort(_("invalid chunk length %d") % l)
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
28 return ""
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
29 return readexactly(stream, l - 4)
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
30
5368
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
31 def chunkheader(length):
9437
1c4e4004f3a6 Improve some docstrings relating to changegroups and prepush().
Greg Ward <greg-hg@gerg.ca>
parents: 9087
diff changeset
32 """return a changegroup chunk header (string)"""
5368
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
33 return struct.pack(">l", length + 4)
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
34
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
35 def closechunk():
9437
1c4e4004f3a6 Improve some docstrings relating to changegroups and prepush().
Greg Ward <greg-hg@gerg.ca>
parents: 9087
diff changeset
36 """return a changegroup chunk header (string) for a zero-length chunk"""
1981
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
37 return struct.pack(">l", 0)
736b6c96bbbc make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
diff changeset
38
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
39 class nocompress(object):
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
40 def compress(self, x):
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
41 return x
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
42 def flush(self):
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
43 return ""
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
44
3662
f4dc02d7fb71 unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents: 3660
diff changeset
45 bundletypes = {
3704
9c1737a3e254 fix writebundle for bz2 bundles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3662
diff changeset
46 "": ("", nocompress),
9c1737a3e254 fix writebundle for bz2 bundles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3662
diff changeset
47 "HG10UN": ("HG10UN", nocompress),
3762
b9d3e12da485 changegroup.py: delay the loading of the bz2 and zlib modules
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3706
diff changeset
48 "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
b9d3e12da485 changegroup.py: delay the loading of the bz2 and zlib modules
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3706
diff changeset
49 "HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
3662
f4dc02d7fb71 unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents: 3660
diff changeset
50 }
f4dc02d7fb71 unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents: 3660
diff changeset
51
10356
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
52 def collector(cl, mmfs, files):
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
53 # Gather information about changeset nodes going out in a bundle.
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
54 # We want to gather manifests needed and filelogs affected.
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
55 def collect(node):
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
56 c = cl.read(node)
11648
801533a52799 changegroup*(): use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10430
diff changeset
57 files.update(c[3])
10356
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
58 mmfs.setdefault(c[0], node)
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
59 return collect
bc2414948012 localrepo: unify changegroup and changegroupsubset code paths a bit
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10263
diff changeset
60
9087
f48454a279b9 typos: "it's" -> "its"
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
61 # hgweb uses this list to communicate its preferred type
6152
c050548307a4 hgweb: use bundletypes from mercurial.changegroup
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5906
diff changeset
62 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
c050548307a4 hgweb: use bundletypes from mercurial.changegroup
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5906
diff changeset
63
3706
0d810798acb1 Use 'bundletype' instead of 'type' to not shadow built-in function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3705
diff changeset
64 def writebundle(cg, filename, bundletype):
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
65 """Write a bundle file and return its filename.
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
66
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
67 Existing files will not be overwritten.
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
68 If no filename is specified, a temporary file is created.
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
69 bz2 compression can be turned off.
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
70 The bundle file will be deleted in case of errors.
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
71 """
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
72
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
73 fh = None
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
74 cleanup = None
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
75 try:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
76 if filename:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
77 fh = open(filename, "wb")
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
78 else:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
79 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
80 fh = os.fdopen(fd, "wb")
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
81 cleanup = filename
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
82
3706
0d810798acb1 Use 'bundletype' instead of 'type' to not shadow built-in function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3705
diff changeset
83 header, compressor = bundletypes[bundletype]
3704
9c1737a3e254 fix writebundle for bz2 bundles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3662
diff changeset
84 fh.write(header)
9c1737a3e254 fix writebundle for bz2 bundles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3662
diff changeset
85 z = compressor()
3662
f4dc02d7fb71 unduplicate bundle writing code from httprepo
Matt Mackall <mpm@selenic.com>
parents: 3660
diff changeset
86
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
87 # parse the changegroup data, otherwise we will block
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
88 # in case of sshrepo because we don't know the end of the stream
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
89
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
90 # an empty chunkgroup is the end of the changegroup
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
91 # a changegroup has at least 2 chunkgroups (changelog and manifest).
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
92 # after that, an empty chunkgroup is the end of the changegroup
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
93 empty = False
5906
0136d7f58982 allow the creation of bundles with empty changelog/manifest chunks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5368
diff changeset
94 count = 0
0136d7f58982 allow the creation of bundles with empty changelog/manifest chunks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5368
diff changeset
95 while not empty or count <= 2:
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
96 empty = True
5906
0136d7f58982 allow the creation of bundles with empty changelog/manifest chunks
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5368
diff changeset
97 count += 1
12335
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
98 while 1:
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
99 chunk = getchunk(cg)
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
100 if not chunk:
e21fe9c5fb25 bundle: get rid of chunkiter
Matt Mackall <mpm@selenic.com>
parents: 12334
diff changeset
101 break
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
102 empty = False
5368
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
103 fh.write(z.compress(chunkheader(len(chunk))))
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
104 pos = 0
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
105 while pos < len(chunk):
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
106 next = pos + 2**20
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
107 fh.write(z.compress(chunk[pos:next]))
61462e7d62ed changegroup: avoid large copies
Matt Mackall <mpm@selenic.com>
parents: 3932
diff changeset
108 pos = next
3659
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
109 fh.write(z.compress(closechunk()))
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
110 fh.write(z.flush())
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
111 cleanup = None
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
112 return filename
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
113 finally:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
114 if fh is not None:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
115 fh.close()
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
116 if cleanup is not None:
025f68f22ae2 move write_bundle to changegroup.py
Matt Mackall <mpm@selenic.com>
parents: 2470
diff changeset
117 os.unlink(cleanup)
3660
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
118
12041
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
119 def decompressor(fh, alg):
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
120 if alg == 'UN':
6154
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
121 return fh
12041
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
122 elif alg == 'GZ':
6154
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
123 def generator(f):
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
124 zd = zlib.decompressobj()
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
125 for chunk in f:
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
126 yield zd.decompress(chunk)
12041
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
127 elif alg == 'BZ':
3660
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
128 def generator(f):
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
129 zd = bz2.BZ2Decompressor()
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
130 zd.decompress("BZ")
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
131 for chunk in util.filechunkiter(f, 4096):
8500a13ec44b create a readbundle function
Matt Mackall <mpm@selenic.com>
parents: 3659
diff changeset
132 yield zd.decompress(chunk)
12041
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
133 else:
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
134 raise util.Abort("unknown bundle compression '%s'" % alg)
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
135 return util.chunkbuffer(generator(fh))
12041
270fb4d39153 bundle: factor out decompressor
Matt Mackall <mpm@selenic.com>
parents: 11648
diff changeset
136
12043
bef5effb3db0 bundle: introduce bundle class
Matt Mackall <mpm@selenic.com>
parents: 12042
diff changeset
137 class unbundle10(object):
bef5effb3db0 bundle: introduce bundle class
Matt Mackall <mpm@selenic.com>
parents: 12042
diff changeset
138 def __init__(self, fh, alg):
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
139 self._stream = decompressor(fh, alg)
12044
bcc7139521b7 bundlerepo: remove duplication of bundle decompressors
Matt Mackall <mpm@selenic.com>
parents: 12043
diff changeset
140 self._type = alg
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
141 self.callback = None
12044
bcc7139521b7 bundlerepo: remove duplication of bundle decompressors
Matt Mackall <mpm@selenic.com>
parents: 12043
diff changeset
142 def compressed(self):
bcc7139521b7 bundlerepo: remove duplication of bundle decompressors
Matt Mackall <mpm@selenic.com>
parents: 12043
diff changeset
143 return self._type != 'UN'
12043
bef5effb3db0 bundle: introduce bundle class
Matt Mackall <mpm@selenic.com>
parents: 12042
diff changeset
144 def read(self, l):
bef5effb3db0 bundle: introduce bundle class
Matt Mackall <mpm@selenic.com>
parents: 12042
diff changeset
145 return self._stream.read(l)
12330
e527b8635881 bundle: make unbundle object seekable
Matt Mackall <mpm@selenic.com>
parents: 12329
diff changeset
146 def seek(self, pos):
e527b8635881 bundle: make unbundle object seekable
Matt Mackall <mpm@selenic.com>
parents: 12329
diff changeset
147 return self._stream.seek(pos)
e527b8635881 bundle: make unbundle object seekable
Matt Mackall <mpm@selenic.com>
parents: 12329
diff changeset
148 def tell(self):
12332
680fe77ab5b8 bundlerepo: use bundle objects everywhere
Matt Mackall <mpm@selenic.com>
parents: 12330
diff changeset
149 return self._stream.tell()
12347
6277a9469dff bundlerepo: restore close() method
Matt Mackall <mpm@selenic.com>
parents: 12336
diff changeset
150 def close(self):
6277a9469dff bundlerepo: restore close() method
Matt Mackall <mpm@selenic.com>
parents: 12336
diff changeset
151 return self._stream.close()
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
152
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
153 def chunklength(self):
13459
acbe171c8fbe changegroup: fix typo introduced in 9f2c407caf34
Jim Hague <jim.hague@acm.org>
parents: 13458
diff changeset
154 d = readexactly(self._stream, 4)
13458
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
155 l = struct.unpack(">l", d)[0]
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
156 if l <= 4:
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
157 if l:
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
158 raise util.Abort(_("invalid chunk length %d") % l)
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
159 return 0
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
160 if self.callback:
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
161 self.callback()
13458
9f2c407caf34 changegroup: don't accept odd chunk headers
Mads Kiilerich <mads@kiilerich.com>
parents: 13457
diff changeset
162 return l - 4
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
163
12333
44c7dfc2f6a3 bundle: make getchunk() a method
Matt Mackall <mpm@selenic.com>
parents: 12332
diff changeset
164 def chunk(self):
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
165 """return the next chunk from changegroup 'source' as a string"""
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
166 l = self.chunklength()
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
167 return readexactly(self._stream, l)
12334
50946802593d bundle: refactor progress callback
Matt Mackall <mpm@selenic.com>
parents: 12333
diff changeset
168
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
169 def parsechunk(self):
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
170 l = self.chunklength()
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
171 if not l:
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
172 return {}
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
173 h = readexactly(self._stream, 80)
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
174 node, p1, p2, cs = struct.unpack("20s20s20s20s", h)
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
175 data = readexactly(self._stream, l - 80)
12336
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
176 return dict(node=node, p1=p1, p2=p2, cs=cs, data=data)
9d234f7d8a77 bundle: move chunk parsing into unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12335
diff changeset
177
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
178 class headerlessfixup(object):
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
179 def __init__(self, fh, h):
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
180 self._h = h
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
181 self._fh = fh
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
182 def read(self, n):
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
183 if self._h:
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
184 d, self._h = self._h[:n], self._h[n:]
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
185 if len(d) < n:
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
186 d += readexactly(self._fh, n - len(d))
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
187 return d
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
188 return readexactly(self._fh, n)
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
189
6154
ef1c5a3b653d improve changegroup.readbundle(), use it in hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6152
diff changeset
190 def readbundle(fh, fname):
13457
e74fe15dc7fd changegroup: verify all stream reads
Mads Kiilerich <mads@kiilerich.com>
parents: 13456
diff changeset
191 header = readexactly(fh, 6)
12042
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
192
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
193 if not fname:
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
194 fname = "stream"
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
195 if not header.startswith('HG') and header.startswith('\0'):
12329
7458de933f26 bundle: push chunkbuffer down into decompress
Matt Mackall <mpm@selenic.com>
parents: 12044
diff changeset
196 fh = headerlessfixup(fh, header)
12042
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
197 header = "HG10UN"
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
198
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
199 magic, version, alg = header[0:2], header[2:4], header[4:6]
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
200
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
201 if magic != 'HG':
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
202 raise util.Abort(_('%s: not a Mercurial bundle') % fname)
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
203 if version != '10':
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 12041
diff changeset
204 raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
12043
bef5effb3db0 bundle: introduce bundle class
Matt Mackall <mpm@selenic.com>
parents: 12042
diff changeset
205 return unbundle10(fh, alg)