diff -r 63659b809021 -r 984850270acb mercurial/wireproto.py --- a/mercurial/wireproto.py Mon Apr 07 18:10:50 2014 -0700 +++ b/mercurial/wireproto.py Fri Apr 04 17:15:25 2014 -0700 @@ -9,7 +9,7 @@ from i18n import _ from node import bin, hex import changegroup as changegroupmod -import peer, error, encoding, util, store +import peer, error, encoding, util, store, exchange class abstractserverproto(object): @@ -754,46 +754,36 @@ def unbundle(repo, proto, heads): their_heads = decodelist(heads) - def check_heads(): - heads = repo.heads() - heads_hash = util.sha1(''.join(sorted(heads))).digest() - return (their_heads == ['force'] or their_heads == heads or - their_heads == ['hashed', heads_hash]) + try: + proto.redirect() - proto.redirect() + exchange.check_heads(repo, their_heads, 'preparing changes') - # fail early if possible - if not check_heads(): - return pusherr('repository changed while preparing changes - ' - 'please try again') - - # write bundle data to temporary file because it can be big - fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') - fp = os.fdopen(fd, 'wb+') - r = 0 - try: - proto.getfile(fp) - lock = repo.lock() + # write bundle data to temporary file because it can be big + fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') + fp = os.fdopen(fd, 'wb+') + r = 0 try: - if not check_heads(): - # someone else committed/pushed/unbundled while we - # were transferring data - return pusherr('repository changed while uploading changes - ' - 'please try again') - - # push can proceed - fp.seek(0) - gen = changegroupmod.readbundle(fp, None) - + proto.getfile(fp) + lock = repo.lock() try: - r = changegroupmod.addchangegroup(repo, gen, 'serve', - proto._client()) - except util.Abort, inst: - sys.stderr.write("abort: %s\n" % inst) + exchange.check_heads(repo, their_heads, 'uploading changes') + + # push can proceed + fp.seek(0) + gen = changegroupmod.readbundle(fp, None) + + try: + r = changegroupmod.addchangegroup(repo, gen, 'serve', + proto._client()) + except util.Abort, inst: + sys.stderr.write("abort: %s\n" % inst) + finally: + lock.release() + return pushres(r) + finally: - lock.release() - return pushres(r) - - finally: - fp.close() - os.unlink(tempname) + fp.close() + os.unlink(tempname) + except exchange.PushRaced, exc: + return pusherr(str(exc))