sapling/bundle2hooks.py
Tony Tung e8afb24cc7 [bundle2hooks] allow hook arguments to be stored on the operation object
Summary:
Some bundle2 handlers (such as pushvars) run prior to the acquisition of the lock.  In order to have those handlers be able to set hook variables, we have to save the hook variables onto the bundle object, rather than the transaction object.

Once the transaction is retrieved, we drain all the hook arguments into the transaction.  Further attempts to call `addhookargs will cause an abort.

An alternative to aborting is to save the transaction, and pass further arguments to the transaction.  I believe this is an inferior choice because it is masking a bug.

Test Plan: run ./verify_reviewedby_info.t in opsfiles with D2880506 patched in.  passed.

Reviewers: #sourcecontrol, durham

Reviewed By: durham

Subscribers: durham, mitrandir

Differential Revision: https://phabricator.fb.com/D2898401

Signature: t1:2898401:1454615031:94933cf513eaa06c5b60686ec5d65a563ddc31c4
2016-02-04 15:59:17 -08:00

47 lines
1.7 KiB
Python

# bundle2hooks.py - fix bundle2's support for hooks prior to lock acquisition.
#
# Copyright 2012 Facebook
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''Hooks arguments are typically stored on the transaction object. However, we
may want to add hooks arguments without starting a transaction. This allows us
to queue hook arguments on the bundle2 operation object.
'''
from mercurial import bundle2
from extutil import replaceclass
def reposetup(ui, repo):
@replaceclass(bundle2, 'bundleoperation')
class bundleoperationhooked(bundle2.bundleoperation):
def __init__(self, repo, transactiongetter, *args, **kwargs):
def gettransaction():
transaction = transactiongetter()
if self.hookargs is not None:
# the ones added to the transaction supercede those added to
# the operation.
self.hookargs.update(transaction.hookargs)
transaction.hookargs = self.hookargs
# mark the hookargs as flushed. further attempts to add to
# hookargs will result in an abort.
self.hookargs = None
return transaction
super(bundleoperationhooked, self).__init__(repo, gettransaction,
*args, **kwargs)
self.hookargs = {}
def addhookargs(self, hookargs):
if self.hookargs is None:
raise error.Abort(_('attempted to add hooks to operation after '
'transaction started'))
self.hookargs.update(hookargs)