[PATCH 2 of 2 V3] debuglocks: allow setting a lock

Paul Morelle paul.morelle at octobus.net
Sun Nov 19 22:54:51 EST 2017


# HG changeset patch
# User Paul Morelle <paul.morelle at octobus.net>
# Date 1510497286 -3600
#      Sun Nov 12 15:34:46 2017 +0100
# Node ID e9f4ce1f42464b7670618986f0762f016e33e284
# Parent  9b602162e10949a80e90d9732bb654b430e0b22a
# EXP-Topic debugsetlocks
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r e9f4ce1f4246
debuglocks: allow setting a lock

diff -r 9b602162e109 -r e9f4ce1f4246 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
@@ -77,6 +77,8 @@
 
 command = registrar.command()
 
+_confirmlockremovalmsg = _("ready to release the lock (Y)? $$ &Yes")
+
 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
 def debugancestor(ui, repo, *args):
     """find the ancestor revision of two revisions in a given index"""
@@ -1173,7 +1175,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
@@ -1192,6 +1197,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.
 
     """
@@ -1203,6 +1212,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(_confirmlockremovalmsg)
+            return 0
+    finally:
+        release(*locks)
+
     now = time.time()
     held = 0
 
diff -r 9b602162e109 -r e9f4ce1f4246 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
@@ -272,7 +272,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 9b602162e109 -r e9f4ce1f4246 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
@@ -133,26 +135,16 @@
   >         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 <<EOF
-  > 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 "$@"
   > }
-
-  $ dolock lock &
+  $ dolock -s &
   $ waitlock .hg/store/lock
+  ready to release the lock (Y)?  (no-eol)
 
   $ hg debuglocks
   lock:  user *, process * (*s) (glob)
@@ -160,11 +152,16 @@
   [1]
   $ touch .hg/unlock
   $ wait
+   y
+  $ ls -l .hg/store/lock
+  ls: cannot access '.hg/store/lock': No such file or directory
+  [2]
 
 * Test setting the wlock
 
-  $ dolock wlock &
+  $ dolock -S &
   $ waitlock .hg/wlock
+  ready to release the lock (Y)?  (no-eol)
 
   $ hg debuglocks
   lock:  free
@@ -172,18 +169,35 @@
   [1]
   $ touch .hg/unlock
   $ wait
+   y
+  $ ls -l .hg/wlock
+  ls: cannot access '.hg/wlock': No such file or directory
+  [2]
 
 * Test setting both locks
 
-  $ dolock wlock lock &
+  $ dolock -Ss &
   $ waitlock .hg/wlock && waitlock .hg/store/lock
+  ready to release the lock (Y)?  (no-eol)
 
   $ 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
+   y
 
   $ hg debuglocks
   lock:  free
@@ -191,8 +205,9 @@
 
 * Test forcing the lock
 
-  $ dolock lock &
+  $ dolock -s &
   $ waitlock .hg/store/lock
+  ready to release the lock (Y)?  (no-eol)
 
   $ hg debuglocks
   lock:  user *, process * (*s) (glob)
@@ -207,11 +222,13 @@
 
   $ touch .hg/unlock
   $ wait
+   y
 
 * Test forcing the wlock
 
-  $ dolock wlock &
+  $ dolock -S &
   $ waitlock .hg/wlock
+  ready to release the lock (Y)?  (no-eol)
 
   $ hg debuglocks
   lock:  free
@@ -226,6 +243,7 @@
 
   $ touch .hg/unlock
   $ wait
+   y
 
 Test WdirUnsupported exception
 


More information about the Mercurial-devel mailing list