7 |
7 |
8 import cStringIO, zlib, bz2, tempfile, errno, os, sys |
8 import cStringIO, zlib, bz2, tempfile, errno, os, sys |
9 from mercurial import util, streamclone |
9 from mercurial import util, streamclone |
10 from mercurial.i18n import gettext as _ |
10 from mercurial.i18n import gettext as _ |
11 from mercurial.node import * |
11 from mercurial.node import * |
|
12 from mercurial import changegroup as changegroupmod |
12 from common import HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
13 from common import HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
13 |
14 |
14 # __all__ is populated with the allowed commands. Be sure to add to it if |
15 # __all__ is populated with the allowed commands. Be sure to add to it if |
15 # you're adding a new command, or the new command won't work. |
16 # you're adding a new command, or the new command won't work. |
16 |
17 |
165 req.write(_('unsynced changes\n')) |
166 req.write(_('unsynced changes\n')) |
166 return |
167 return |
167 |
168 |
168 fp.seek(0) |
169 fp.seek(0) |
169 header = fp.read(6) |
170 header = fp.read(6) |
170 if not header.startswith("HG"): |
171 if header.startswith('HG') and not header.startswith('HG10'): |
171 # old client with uncompressed bundle |
172 raise ValueError('unknown bundle version') |
172 def generator(f): |
173 elif header not in changegroupmod.bundletypes: |
173 yield header |
174 raise ValueError('unknown bundle compression type') |
174 for chunk in f: |
175 gen = changegroupmod.unbundle(header, fp) |
175 yield chunk |
|
176 elif not header.startswith("HG10"): |
|
177 req.write("0\n") |
|
178 req.write(_("unknown bundle version\n")) |
|
179 return |
|
180 elif header == "HG10GZ": |
|
181 def generator(f): |
|
182 zd = zlib.decompressobj() |
|
183 for chunk in f: |
|
184 yield zd.decompress(chunk) |
|
185 elif header == "HG10BZ": |
|
186 def generator(f): |
|
187 zd = bz2.BZ2Decompressor() |
|
188 zd.decompress("BZ") |
|
189 for chunk in f: |
|
190 yield zd.decompress(chunk) |
|
191 elif header == "HG10UN": |
|
192 def generator(f): |
|
193 for chunk in f: |
|
194 yield chunk |
|
195 else: |
|
196 req.write("0\n") |
|
197 req.write(_("unknown bundle compression type\n")) |
|
198 return |
|
199 gen = generator(util.filechunkiter(fp, 4096)) |
|
200 |
176 |
201 # send addchangegroup output to client |
177 # send addchangegroup output to client |
202 |
178 |
203 old_stdout = sys.stdout |
179 old_stdout = sys.stdout |
204 sys.stdout = cStringIO.StringIO() |
180 sys.stdout = cStringIO.StringIO() |
205 |
181 |
206 try: |
182 try: |
207 url = 'remote:%s:%s' % (proto, |
183 url = 'remote:%s:%s' % (proto, |
208 req.env.get('REMOTE_HOST', '')) |
184 req.env.get('REMOTE_HOST', '')) |
209 try: |
185 try: |
210 ret = web.repo.addchangegroup( |
186 ret = web.repo.addchangegroup(gen, 'serve', url) |
211 util.chunkbuffer(gen), 'serve', url) |
|
212 except util.Abort, inst: |
187 except util.Abort, inst: |
213 sys.stdout.write("abort: %s\n" % inst) |
188 sys.stdout.write("abort: %s\n" % inst) |
214 ret = 0 |
189 ret = 0 |
215 finally: |
190 finally: |
216 val = sys.stdout.getvalue() |
191 val = sys.stdout.getvalue() |
217 sys.stdout = old_stdout |
192 sys.stdout = old_stdout |
218 req.write('%d\n' % ret) |
193 req.write('%d\n' % ret) |
219 req.write(val) |
194 req.write(val) |
220 finally: |
195 finally: |
221 del lock |
196 del lock |
|
197 except ValueError, inst: |
|
198 req.write('0\n') |
|
199 req.write(str(inst) + '\n') |
222 except (OSError, IOError), inst: |
200 except (OSError, IOError), inst: |
223 req.write('0\n') |
201 req.write('0\n') |
224 filename = getattr(inst, 'filename', '') |
202 filename = getattr(inst, 'filename', '') |
225 # Don't send our filesystem layout to the client |
203 # Don't send our filesystem layout to the client |
226 if filename.startswith(web.repo.root): |
204 if filename.startswith(web.repo.root): |