Mercurial > hg
changeset 20952:b24ee5076b94
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.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Wed, 02 Apr 2014 23:56:49 -0700 |
parents | f977c732bf34 |
children | 8d853cad6b14 |
files | mercurial/bundle2.py tests/test-bundle2.t |
diffstat | 2 files changed, 26 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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')
--- 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))