mercurial/wireproto.py
changeset 20967 984850270acb
parent 20933 d3775db748a0
child 20968 33d5fdd9bd99
equal deleted inserted replaced
20966:63659b809021 20967:984850270acb
     7 
     7 
     8 import urllib, tempfile, os, sys
     8 import urllib, tempfile, os, sys
     9 from i18n import _
     9 from i18n import _
    10 from node import bin, hex
    10 from node import bin, hex
    11 import changegroup as changegroupmod
    11 import changegroup as changegroupmod
    12 import peer, error, encoding, util, store
    12 import peer, error, encoding, util, store, exchange
    13 
    13 
    14 
    14 
    15 class abstractserverproto(object):
    15 class abstractserverproto(object):
    16     """abstract class that summarizes the protocol API
    16     """abstract class that summarizes the protocol API
    17 
    17 
   752 
   752 
   753 @wireprotocommand('unbundle', 'heads')
   753 @wireprotocommand('unbundle', 'heads')
   754 def unbundle(repo, proto, heads):
   754 def unbundle(repo, proto, heads):
   755     their_heads = decodelist(heads)
   755     their_heads = decodelist(heads)
   756 
   756 
   757     def check_heads():
       
   758         heads = repo.heads()
       
   759         heads_hash = util.sha1(''.join(sorted(heads))).digest()
       
   760         return (their_heads == ['force'] or their_heads == heads or
       
   761                 their_heads == ['hashed', heads_hash])
       
   762 
       
   763     proto.redirect()
       
   764 
       
   765     # fail early if possible
       
   766     if not check_heads():
       
   767         return pusherr('repository changed while preparing changes - '
       
   768                        'please try again')
       
   769 
       
   770     # write bundle data to temporary file because it can be big
       
   771     fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
       
   772     fp = os.fdopen(fd, 'wb+')
       
   773     r = 0
       
   774     try:
   757     try:
   775         proto.getfile(fp)
   758         proto.redirect()
   776         lock = repo.lock()
   759 
   777         try:
   760         exchange.check_heads(repo, their_heads, 'preparing changes')
   778             if not check_heads():
   761 
   779                 # someone else committed/pushed/unbundled while we
   762         # write bundle data to temporary file because it can be big
   780                 # were transferring data
   763         fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
   781                 return pusherr('repository changed while uploading changes - '
   764         fp = os.fdopen(fd, 'wb+')
   782                                'please try again')
   765         r = 0
   783 
   766         try:
   784             # push can proceed
   767             proto.getfile(fp)
   785             fp.seek(0)
   768             lock = repo.lock()
   786             gen = changegroupmod.readbundle(fp, None)
       
   787 
       
   788             try:
   769             try:
   789                 r = changegroupmod.addchangegroup(repo, gen, 'serve',
   770                 exchange.check_heads(repo, their_heads, 'uploading changes')
   790                                                   proto._client())
   771 
   791             except util.Abort, inst:
   772                 # push can proceed
   792                 sys.stderr.write("abort: %s\n" % inst)
   773                 fp.seek(0)
       
   774                 gen = changegroupmod.readbundle(fp, None)
       
   775 
       
   776                 try:
       
   777                     r = changegroupmod.addchangegroup(repo, gen, 'serve',
       
   778                                                       proto._client())
       
   779                 except util.Abort, inst:
       
   780                     sys.stderr.write("abort: %s\n" % inst)
       
   781             finally:
       
   782                 lock.release()
       
   783             return pushres(r)
       
   784 
   793         finally:
   785         finally:
   794             lock.release()
   786             fp.close()
   795         return pushres(r)
   787             os.unlink(tempname)
   796 
   788     except exchange.PushRaced, exc:
   797     finally:
   789         return pusherr(str(exc))
   798         fp.close()
       
   799         os.unlink(tempname)