comparison mercurial/wireproto.py @ 20967:984850270acb

unbundle: extract checkheads in its own function We are going to refactor the unbundle function to have it working on a local repository too. Having this function extracted will ease the process. In the case of non-matching heads, the function now directly raises an exception. The top level of the function is catching it.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Fri, 04 Apr 2014 17:15:25 -0700
parents d3775db748a0
children 33d5fdd9bd99
comparison
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)