# HG changeset patch # User Siddharth Agarwal # Date 2015-10-06 20:19:05 # Node ID e72b62b154b04c1d62ac82baec88dcc7f33a5e20 # Parent e8564e04382d49cc2e50f1a2d0d6e62fd240ad1a localrepo: prevent wlock from being inherited when a transaction is running Review feedback from Pierre-Yves David. A separate line of work is working to ensure that dirstate writes are written to a separate 'pending' file while a transaction is active. Lock inheritance currently conflicts with that, so dodge the issue by simply preventing inheritance while a transaction is running. Custom merge drivers aren't going to run inside a transaction, so this doesn't affect that. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1212,7 +1212,7 @@ class localrepository(object): ce.refresh() def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc, - parentenvvar=None): + inheritchecker=None, parentenvvar=None): parentlock = None # the contents of parentenvvar are used by the underlying lock to # determine whether it can be inherited @@ -1221,6 +1221,7 @@ class localrepository(object): try: l = lockmod.lock(vfs, lockname, 0, releasefn=releasefn, acquirefn=acquirefn, desc=desc, + inheritchecker=inheritchecker, parentlock=parentlock) except error.LockHeld as inst: if not wait: @@ -1265,6 +1266,11 @@ class localrepository(object): self._lockref = weakref.ref(l) return l + def _wlockchecktransaction(self): + if self.currenttransaction() is not None: + raise error.LockInheritanceContractViolation( + 'wlock cannot be inherited in the middle of a transaction') + def wlock(self, wait=True): '''Lock the non-store parts of the repository (everything under .hg except .hg/store) and return a weak reference to the lock. @@ -1296,7 +1302,9 @@ class localrepository(object): l = self._lock(self.vfs, "wlock", wait, unlock, self.invalidatedirstate, _('working directory of %s') % - self.origroot, parentenvvar='HG_WLOCK_LOCKER') + self.origroot, + inheritchecker=self._wlockchecktransaction, + parentenvvar='HG_WLOCK_LOCKER') self._wlockref = weakref.ref(l) return l diff --git a/tests/test-lock.py b/tests/test-lock.py --- a/tests/test-lock.py +++ b/tests/test-lock.py @@ -260,7 +260,7 @@ class testlock(unittest.TestCase): state.assertacquirecalled(True) def tryinherit(): - with lock.inherit() as lockname: + with lock.inherit(): pass self.assertRaises(error.LockInheritanceContractViolation, tryinherit)