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) |
|