diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
index 8d72e29ad1e093cbe71ce271ea18e40c30a47b8b_bWVyY3VyaWFsL3NjbXV0aWwucHk=..e0dbfbd4062c72fa60958397d19fe350d6a0ebce_bWVyY3VyaWFsL3NjbXV0aWwucHk= 100644
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -159,6 +159,7 @@
     # Global exception handling, alphabetically
     # Mercurial-specific first, followed by built-in and library exceptions
     except error.LockHeld as inst:
+        detailed_exit_code = 20
         if inst.errno == errno.ETIMEDOUT:
             reason = _(b'timed out waiting for lock held by %r') % (
                 pycompat.bytestr(inst.locker)
@@ -172,6 +173,7 @@
         if not inst.locker:
             ui.error(_(b"(lock might be very busy)\n"))
     except error.LockUnavailable as inst:
+        detailed_exit_code = 20
         ui.error(
             _(b"abort: could not lock %s: %s\n")
             % (
diff --git a/tests/test-lock-badness.t b/tests/test-lock-badness.t
index 8d72e29ad1e093cbe71ce271ea18e40c30a47b8b_dGVzdHMvdGVzdC1sb2NrLWJhZG5lc3MudA==..e0dbfbd4062c72fa60958397d19fe350d6a0ebce_dGVzdHMvdGVzdC1sb2NrLWJhZG5lc3MudA== 100644
--- a/tests/test-lock-badness.t
+++ b/tests/test-lock-badness.t
@@ -136,6 +136,6 @@
   pushing to a
   searching for changes
   abort: could not lock repository a: Permission denied
-  [255]
+  [20]
 
   $ chmod 700 a/.hg/store
diff --git a/tests/test-phases-exchange.t b/tests/test-phases-exchange.t
index 8d72e29ad1e093cbe71ce271ea18e40c30a47b8b_dGVzdHMvdGVzdC1waGFzZXMtZXhjaGFuZ2UudA==..e0dbfbd4062c72fa60958397d19fe350d6a0ebce_dGVzdHMvdGVzdC1waGFzZXMtZXhjaGFuZ2UudA== 100644
--- a/tests/test-phases-exchange.t
+++ b/tests/test-phases-exchange.t
@@ -1327,7 +1327,7 @@
   waiting for lock on repository $TESTTMP/Upsilon held by ''
   abort: repository $TESTTMP/Upsilon: timed out waiting for lock held by ''
   (lock might be very busy)
-  [255]
+  [20]
   $ rm .hg/store/lock
 
   $ cd ..