mercurial/wireproto.py
changeset 11593 d054cc5c7737
parent 11592 26e0782b8380
child 11594 67863f9d805f
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 }