# HG changeset patch # User Paul Morelle # Date 1510497286 -3600 # Node ID 12055fb3ba305bbd94c808d7fb7c51b5f555d301 # Parent a43b2dd95e4f531fc8680bf202e87743d859baa5 debuglocks: allow setting a lock diff -r a43b2dd95e4f -r 12055fb3ba30 mercurial/debugcommands.py --- a/mercurial/debugcommands.py Sun Nov 12 15:34:19 2017 +0100 +++ b/mercurial/debugcommands.py Sun Nov 12 15:34:46 2017 +0100 @@ -1275,7 +1275,10 @@ @command('debuglocks', [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')), ('W', 'force-wlock', None, - _('free the working state lock (DANGEROUS)'))], + _('free the working state lock (DANGEROUS)')), + ('s', 'set-lock', None, _('set the store lock until stopped')), + ('S', 'set-wlock', None, + _('set the working state lock until stopped'))], _('[OPTION]...')) def debuglocks(ui, repo, **opts): """show or modify state of locks @@ -1294,6 +1297,10 @@ instance, on a shared filesystem). Removing locks may also be blocked by filesystem permissions. + Setting a lock will prevent other commands from changing the data. + The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs. + The set locks are removed when the command exits. + Returns 0 if no locks are held. """ @@ -1305,6 +1312,24 @@ if opts.get(r'force_lock') or opts.get(r'force_wlock'): return 0 + locks = [] + try: + if opts.get(r'set_wlock'): + try: + locks.append(repo.wlock(False)) + except error.LockHeld: + raise error.Abort(_('wlock is already held')) + if opts.get(r'set_lock'): + try: + locks.append(repo.lock(False)) + except error.LockHeld: + raise error.Abort(_('lock is already held')) + if len(locks): + ui.promptchoice(_("ready to release the lock (y)? $$ &Yes")) + return 0 + finally: + release(*locks) + now = time.time() held = 0 diff -r a43b2dd95e4f -r 12055fb3ba30 tests/test-completion.t --- a/tests/test-completion.t Sun Nov 12 15:34:19 2017 +0100 +++ b/tests/test-completion.t Sun Nov 12 15:34:46 2017 +0100 @@ -274,7 +274,7 @@ debuginstall: template debugknown: debuglabelcomplete: - debuglocks: force-lock, force-wlock + debuglocks: force-lock, force-wlock, set-lock, set-wlock debugmergestate: debugnamecomplete: debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template diff -r a43b2dd95e4f -r 12055fb3ba30 tests/test-debugcommands.t --- a/tests/test-debugcommands.t Sun Nov 12 15:34:19 2017 +0100 +++ b/tests/test-debugcommands.t Sun Nov 12 15:34:46 2017 +0100 @@ -1,4 +1,6 @@ $ cat << EOF >> $HGRCPATH + > [ui] + > interactive=yes > [format] > usegeneraldelta=yes > EOF @@ -157,7 +159,7 @@ amount of time, displays error message and returns 1 $ waitlock() { > start=`date +%s` - > timeout=1 + > timeout=5 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do > now=`date +%s` > if [ "`expr $now - $start`" -gt $timeout ]; then @@ -167,25 +169,14 @@ > sleep 0.1 > done > } -dolock [wlock] [lock] will set the locks until interrupted $ dolock() { - > declare -A options - > options=([${1:-nolock}]=1 [${2:-nowlock}]=1) - > python < from mercurial import hg, ui as uimod - > import os - > import time - > - > repo = hg.repository(uimod.ui.load(), path='.') - > `[ -n "${options["wlock"]}" ] && echo "with repo.wlock(False):" || echo "if True:"` - > `[ -n "${options["lock"]}" ] && echo "with repo.lock(False):" || echo "if True:"` - > while not os.path.exists('.hg/unlock'): - > time.sleep(0.1) - > os.unlink('.hg/unlock') - > EOF + > { + > waitlock .hg/unlock + > rm -f .hg/unlock + > echo y + > } | hg debuglocks "$@" > /dev/null > } - - $ dolock lock & + $ dolock -s & $ waitlock .hg/store/lock $ hg debuglocks @@ -194,10 +185,12 @@ [1] $ touch .hg/unlock $ wait + $ [ -f .hg/store/lock ] || echo "There is no lock" + There is no lock * Test setting the wlock - $ dolock wlock & + $ dolock -S & $ waitlock .hg/wlock $ hg debuglocks @@ -206,16 +199,29 @@ [1] $ touch .hg/unlock $ wait + $ [ -f .hg/wlock ] || echo "There is no wlock" + There is no wlock * Test setting both locks - $ dolock wlock lock & + $ dolock -Ss & $ waitlock .hg/wlock && waitlock .hg/store/lock $ hg debuglocks lock: user *, process * (*s) (glob) wlock: user *, process * (*s) (glob) [2] + +* Test failing to set a lock + + $ hg debuglocks -s + abort: lock is already held + [255] + + $ hg debuglocks -S + abort: wlock is already held + [255] + $ touch .hg/unlock $ wait @@ -225,7 +231,7 @@ * Test forcing the lock - $ dolock lock & + $ dolock -s & $ waitlock .hg/store/lock $ hg debuglocks @@ -244,7 +250,7 @@ * Test forcing the wlock - $ dolock wlock & + $ dolock -S & $ waitlock .hg/wlock $ hg debuglocks