Show More
@@ -611,3 +611,20 b' def getbundle(repo, source, heads=None, ' | |||||
611 | temp.write(c) |
|
611 | temp.write(c) | |
612 | temp.seek(0) |
|
612 | temp.seek(0) | |
613 | return bundle2.unbundle20(repo.ui, temp) |
|
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 | 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): | |
@@ -754,46 +754,36 b' def stream(repo, proto):' | |||||
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(): |
|
757 | try: | |
758 | heads = repo.heads() |
|
758 | proto.redirect() | |
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 |
|
759 | |||
763 | proto.redirect() |
|
760 | exchange.check_heads(repo, their_heads, 'preparing changes') | |
764 |
|
761 | |||
765 | # fail early if possible |
|
762 | # write bundle data to temporary file because it can be big | |
766 | if not check_heads(): |
|
763 | fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | |
767 | return pusherr('repository changed while preparing changes - ' |
|
764 | fp = os.fdopen(fd, 'wb+') | |
768 | 'please try again') |
|
765 | r = 0 | |
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() |
|
|||
777 | try: |
|
766 | try: | |
778 | if not check_heads(): |
|
767 | proto.getfile(fp) | |
779 | # someone else committed/pushed/unbundled while we |
|
768 | lock = repo.lock() | |
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 |
|
||||
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 |
|
|
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) |
|
General Comments 0
You need to be logged in to leave comments.
Login now