Mercurial > hg-stable
comparison mercurial/wireproto.py @ 11593:d054cc5c7737
protocol: unify unbundle on the server side
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 15 Jul 2010 11:24:42 -0500 |
parents | 26e0782b8380 |
children | 67863f9d805f |
comparison
equal
deleted
inserted
replaced
11592:26e0782b8380 | 11593:d054cc5c7737 |
---|---|
3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com> | 3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com> |
4 # | 4 # |
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 import urllib, tempfile, os | |
8 from i18n import _ | 9 from i18n import _ |
9 from node import bin, hex | 10 from node import bin, hex |
10 import urllib | 11 import changegroup as changegroupmod |
11 import streamclone, repo, error, encoding | 12 import streamclone, repo, error, encoding, util |
12 import pushkey as pushkey_ | 13 import pushkey as pushkey_ |
13 | 14 |
14 # client side | 15 # client side |
15 | 16 |
16 class wirerepository(repo.repository): | 17 class wirerepository(repo.repository): |
196 try: | 197 try: |
197 proto.sendstream(streamclone.stream_out(repo)) | 198 proto.sendstream(streamclone.stream_out(repo)) |
198 except streamclone.StreamException, inst: | 199 except streamclone.StreamException, inst: |
199 return str(inst) | 200 return str(inst) |
200 | 201 |
202 def unbundle(repo, proto, heads): | |
203 their_heads = heads.split() | |
204 | |
205 def check_heads(): | |
206 heads = map(hex, repo.heads()) | |
207 return their_heads == [hex('force')] or their_heads == heads | |
208 | |
209 # fail early if possible | |
210 if not check_heads(): | |
211 repo.respond(_('unsynced changes')) | |
212 return | |
213 | |
214 # write bundle data to temporary file because it can be big | |
215 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | |
216 fp = os.fdopen(fd, 'wb+') | |
217 r = 0 | |
218 proto.redirect() | |
219 try: | |
220 proto.getfile(fp) | |
221 lock = repo.lock() | |
222 try: | |
223 if not check_heads(): | |
224 # someone else committed/pushed/unbundled while we | |
225 # were transferring data | |
226 proto.respond(_('unsynced changes')) | |
227 return | |
228 | |
229 # push can proceed | |
230 fp.seek(0) | |
231 header = fp.read(6) | |
232 if header.startswith('HG'): | |
233 if not header.startswith('HG10'): | |
234 raise ValueError('unknown bundle version') | |
235 elif header not in changegroupmod.bundletypes: | |
236 raise ValueError('unknown bundle compression type') | |
237 gen = changegroupmod.unbundle(header, fp) | |
238 | |
239 try: | |
240 r = repo.addchangegroup(gen, 'serve', proto._client(), | |
241 lock=lock) | |
242 except util.Abort, inst: | |
243 sys.stderr.write("abort: %s\n" % inst) | |
244 finally: | |
245 lock.release() | |
246 proto.respondpush(r) | |
247 | |
248 finally: | |
249 fp.close() | |
250 os.unlink(tempname) | |
251 | |
201 commands = { | 252 commands = { |
202 'between': (between, 'pairs'), | 253 'between': (between, 'pairs'), |
203 'branchmap': (branchmap, ''), | 254 'branchmap': (branchmap, ''), |
204 'branches': (branches, 'nodes'), | 255 'branches': (branches, 'nodes'), |
205 'changegroup': (changegroup, 'roots'), | 256 'changegroup': (changegroup, 'roots'), |
207 'heads': (heads, ''), | 258 'heads': (heads, ''), |
208 'listkeys': (listkeys, 'namespace'), | 259 'listkeys': (listkeys, 'namespace'), |
209 'lookup': (lookup, 'key'), | 260 'lookup': (lookup, 'key'), |
210 'pushkey': (pushkey, 'namespace key old new'), | 261 'pushkey': (pushkey, 'namespace key old new'), |
211 'stream_out': (stream, ''), | 262 'stream_out': (stream, ''), |
263 'unbundle': (unbundle, 'heads'), | |
212 } | 264 } |