Show More
@@ -611,3 +611,20 b' def getbundle(repo, source, heads=None, ' | |||
|
611 | 611 | temp.write(c) |
|
612 | 612 | temp.seek(0) |
|
613 | 613 | return bundle2.unbundle20(repo.ui, temp) |
|
614 | ||
|
615 | class PushRaced(RuntimeError): | |
|
616 | """An exception raised during unbunding that indicate a push race""" | |
|
617 | ||
|
618 | def check_heads(repo, their_heads, context): | |
|
619 | """check if the heads of a repo have been modified | |
|
620 | ||
|
621 | Used by peer for unbundling. | |
|
622 | """ | |
|
623 | heads = repo.heads() | |
|
624 | heads_hash = util.sha1(''.join(sorted(heads))).digest() | |
|
625 | if not (their_heads == ['force'] or their_heads == heads or | |
|
626 | their_heads == ['hashed', heads_hash]): | |
|
627 | # someone else committed/pushed/unbundled while we | |
|
628 | # were transferring data | |
|
629 | raise PushRaced('repository changed while %s - ' | |
|
630 | 'please try again' % context) |
@@ -9,7 +9,7 b' import urllib, tempfile, os, sys' | |||
|
9 | 9 | from i18n import _ |
|
10 | 10 | from node import bin, hex |
|
11 | 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 | 15 | class abstractserverproto(object): |
@@ -754,46 +754,36 b' def stream(repo, proto):' | |||
|
754 | 754 | def unbundle(repo, proto, heads): |
|
755 | 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]) | |
|
757 | try: | |
|
758 | proto.redirect() | |
|
762 | 759 | |
|
763 | proto.redirect() | |
|
760 | exchange.check_heads(repo, their_heads, 'preparing changes') | |
|
764 | 761 | |
|
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: | |
|
775 | proto.getfile(fp) | |
|
776 | lock = repo.lock() | |
|
762 | # write bundle data to temporary file because it can be big | |
|
763 | fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | |
|
764 | fp = os.fdopen(fd, 'wb+') | |
|
765 | r = 0 | |
|
777 | 766 | try: |
|
778 | if not check_heads(): | |
|
779 | # someone else committed/pushed/unbundled while we | |
|
780 | # were transferring data | |
|
781 | return pusherr('repository changed while uploading changes - ' | |
|
782 | 'please try again') | |
|
783 | ||
|
784 | # push can proceed | |
|
785 | fp.seek(0) | |
|
786 | gen = changegroupmod.readbundle(fp, None) | |
|
787 | ||
|
767 | proto.getfile(fp) | |
|
768 | lock = repo.lock() | |
|
788 | 769 | try: |
|
789 | r = changegroupmod.addchangegroup(repo, gen, 'serve', | |
|
790 | proto._client()) | |
|
791 | except util.Abort, inst: | |
|
792 | sys.stderr.write("abort: %s\n" % inst) | |
|
770 | exchange.check_heads(repo, their_heads, 'uploading changes') | |
|
771 | ||
|
772 | # push can proceed | |
|
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 | 785 | finally: |
|
794 |
|
|
|
795 | return pushres(r) | |
|
796 | ||
|
797 | finally: | |
|
798 | fp.close() | |
|
799 | os.unlink(tempname) | |
|
786 | fp.close() | |
|
787 | os.unlink(tempname) | |
|
788 | except exchange.PushRaced, exc: | |
|
789 | return pusherr(str(exc)) |
General Comments 0
You need to be logged in to leave comments.
Login now