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