# HG changeset patch # User Pierre-Yves David # Date 1396508209 25200 # Node ID b24ee5076b94ea446a1e04dd976a1a9e409f0130 # Parent f977c732bf341afe2b74083a58980c91027fbf44 bundle2: make it possible have a global transaction for the unbundling We use the `gettransaction` method approach already used for pull. We need this because we do not know beforehand if the bundle needs a transaction to be created. And (1) we do not want to create a transaction for nothing. (2) Some bundle2 bundles may be read-only and do not require any lock or transaction to be held. diff -r f977c732bf34 -r b24ee5076b94 mercurial/bundle2.py --- a/mercurial/bundle2.py Fri Apr 04 17:47:19 2014 -0500 +++ b/mercurial/bundle2.py Wed Apr 02 23:56:49 2014 -0700 @@ -238,12 +238,23 @@ * a way to construct a bundle response when applicable. """ - def __init__(self, repo): + def __init__(self, repo, transactiongetter): self.repo = repo self.ui = repo.ui self.records = unbundlerecords() + self.gettransaction = transactiongetter -def processbundle(repo, unbundler): +class TransactionUnavailable(RuntimeError): + pass + +def _notransaction(): + """default method to get a transaction while processing a bundle + + Raise an exception to highlight the fact that no transaction was expected + to be created""" + raise TransactionUnavailable() + +def processbundle(repo, unbundler, transactiongetter=_notransaction): """This function process a bundle, apply effect to/from a repo It iterates over each part then searches for and uses the proper handling @@ -254,7 +265,7 @@ Unknown Mandatory part will abort the process. """ - op = bundleoperation(repo) + op = bundleoperation(repo, transactiongetter) # todo: # - replace this is a init function soon. # - exception catching @@ -532,6 +543,12 @@ This is a very early implementation that will massive rework before being inflicted to any end-user. """ + # Make sure we trigger a transaction creation + # + # The addchangegroup function will get a transaction object by itself, but + # we need to make sure we trigger the creation of a transaction object used + # for the whole processing scope. + op.gettransaction() data = StringIO.StringIO(part.data) data.seek(0) cg = changegroup.readbundle(data, 'bundle2part') diff -r f977c732bf34 -r b24ee5076b94 tests/test-bundle2.t --- a/tests/test-bundle2.t Fri Apr 04 17:47:19 2014 -0500 +++ b/tests/test-bundle2.t Wed Apr 02 23:56:49 2014 -0700 @@ -96,13 +96,18 @@ > def cmdunbundle2(ui, repo): > """process a bundle2 stream from stdin on the current repo""" > try: + > tr = None > lock = repo.lock() + > tr = repo.transaction('processbundle') > try: > unbundler = bundle2.unbundle20(ui, sys.stdin) - > op = bundle2.processbundle(repo, unbundler) + > op = bundle2.processbundle(repo, unbundler, lambda: tr) + > tr.close() > except KeyError, exc: > raise util.Abort('missing support for %s' % exc) > finally: + > if tr is not None: + > tr.release() > lock.release() > remains = sys.stdin.read() > ui.write('%i unread bytes\n' % len(remains))