devel: move the lock-checking code into core
If the developer warnings are enabled, bad locking order will be
reported without the need for the contrib extension.
--- a/mercurial/localrepo.py Wed Mar 18 20:59:06 2015 -0700
+++ b/mercurial/localrepo.py Fri Jan 16 02:51:10 2015 -0800
@@ -1189,6 +1189,15 @@
'''Lock the non-store parts of the repository (everything under
.hg except .hg/store) and return a weak reference to the lock.
Use this before modifying files in .hg.'''
+ if (self.ui.configbool('devel', 'all')
+ or self.ui.configbool('devel', 'check-locks')):
+ l = self._lockref and self._lockref()
+ if l is not None and l.held:
+ msg = '"lock" taken before "wlock"\n'
+ if self.ui.tracebackflag:
+ util.debugstacktrace(msg, 1)
+ else:
+ self.ui.write_err(msg)
l = self._wlockref and self._wlockref()
if l is not None and l.held:
l.lock()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-devel-warnings.t Fri Jan 16 02:51:10 2015 -0800
@@ -0,0 +1,49 @@
+
+ $ cat << EOF > buggylocking.py
+ > """A small extension that acquire locks in the wrong order
+ > """
+ >
+ > from mercurial import cmdutil
+ >
+ > cmdtable = {}
+ > command = cmdutil.command(cmdtable)
+ >
+ > @command('buggylocking', [], '')
+ > def buggylocking(ui, repo):
+ > lo = repo.lock()
+ > wl = repo.wlock()
+ > EOF
+
+ $ cat << EOF >> $HGRCPATH
+ > [extensions]
+ > buggylocking=$TESTTMP/buggylocking.py
+ > [devel]
+ > all=1
+ > EOF
+
+ $ hg init lock-checker
+ $ cd lock-checker
+ $ hg buggylocking
+ "lock" taken before "wlock"
+ $ cat << EOF >> $HGRCPATH
+ > [devel]
+ > all=0
+ > check-locks=1
+ > EOF
+ $ hg buggylocking
+ "lock" taken before "wlock"
+ $ hg buggylocking --traceback
+ "lock" taken before "wlock"
+ at:
+ */hg:* in <module> (glob)
+ */mercurial/dispatch.py:* in run (glob)
+ */mercurial/dispatch.py:* in dispatch (glob)
+ */mercurial/dispatch.py:* in _runcatch (glob)
+ */mercurial/dispatch.py:* in _dispatch (glob)
+ */mercurial/dispatch.py:* in runcommand (glob)
+ */mercurial/dispatch.py:* in _runcommand (glob)
+ */mercurial/dispatch.py:* in checkargs (glob)
+ */mercurial/dispatch.py:* in <lambda> (glob)
+ */mercurial/util.py:* in check (glob)
+ $TESTTMP/buggylocking.py:* in buggylocking (glob)
+ $ cd ..