[Updated] [+- ] D11817: sparse: lock the store when updating requirements config

aalekseyev (Arseniy Alekseyev) phabricator at mercurial-scm.org
Mon Dec 6 19:09:27 UTC 2021


aalekseyev updated this revision to Diff 31324.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D11817?vs=31323&id=31324

BRANCH
  stable

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D11817/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D11817

AFFECTED FILES
  mercurial/hg.py
  mercurial/sparse.py
  tests/test-sparse-with-safe-share.t

CHANGE DETAILS

diff --git a/tests/test-sparse-with-safe-share.t b/tests/test-sparse-with-safe-share.t
--- a/tests/test-sparse-with-safe-share.t
+++ b/tests/test-sparse-with-safe-share.t
@@ -16,10 +16,8 @@
   $ echo x > hide
   $ hg ci -Aqm 'initial'
 
-Verify basic --include
+Regression test: checks that this command correctly locks the store
+before updating the store [requirements] config.
 
   $ hg up -q 0
   $ hg debugsparse --include 'hide'
-  devel-warn: write with no lock: "requires" at: *mercurial/scmutil.py:1558 (writerequires) (glob)
-
-TODO: bug in sparse when used together with safe-share^
diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -718,7 +718,7 @@
 
     The new config is written out and a working directory refresh is performed.
     """
-    with repo.wlock(), repo.dirstate.parentchange():
+    with repo.wlock(), repo.lock(), repo.dirstate.parentchange():
         raw = repo.vfs.tryread(b'sparse')
         oldinclude, oldexclude, oldprofiles = parseconfig(
             repo.ui, raw, b'sparse'
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -12,6 +12,7 @@
 import os
 import shutil
 import stat
+import weakref
 
 from .i18n import _
 from .node import (
@@ -677,7 +678,7 @@
         srcpeer = source.peer()  # in case we were called with a localrepo
         branches = (None, branch or [])
         origsource = source = srcpeer.url()
-    srclock = destlock = cleandir = None
+    srclock = destlock = destwlock = cleandir = None
     destpeer = None
     try:
         revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
@@ -865,6 +866,8 @@
                 requirements=dest_reqs,
             )
             destrepo = localrepo.makelocalrepository(ui, destrootpath)
+
+            destwlock = destrepo.wlock()
             destlock = destrepo.lock()
             from . import streamclone  # avoid cycle
 
@@ -873,6 +876,18 @@
             # we need to re-init the repo after manually copying the data
             # into it
             destpeer = peer(srcrepo, peeropts, dest)
+
+            # make the peer aware that is it already locked
+            #
+            # important:
+            #
+            #    We still need to release that lock at the end of the function
+            destpeer.local()._lockref = weakref.ref(destlock)
+            destpeer.local()._wlockref = weakref.ref(destwlock)
+            # dirstate also needs to be copied because `_wlockref` has a reference
+            # to it: this dirstate is saved to disk when the wlock is released
+            destpeer.local().dirstate = destrepo.dirstate
+
             srcrepo.hook(
                 b'outgoing', source=b'clone', node=srcrepo.nodeconstants.nullhex
             )
@@ -1040,6 +1055,8 @@
                     bookmarks.activate(destrepo, update)
             if destlock is not None:
                 release(destlock)
+            if destwlock is not None:
+                release(destlock)
             # here is a tiny windows were someone could end up writing the
             # repository before the cache are sure to be warm. This is "fine"
             # as the only "bad" outcome would be some slowness. That potential
@@ -1047,7 +1064,7 @@
             with destrepo.lock():
                 destrepo.updatecaches(caches=repositorymod.CACHES_POST_CLONE)
     finally:
-        release(srclock, destlock)
+        release(srclock, destlock, destwlock)
         if cleandir is not None:
             shutil.rmtree(cleandir, True)
         if srcpeer is not None:



To: aalekseyev, #hg-reviewers, Alphare
Cc: marmoute, mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mercurial-scm.org/pipermail/mercurial-patches/attachments/20211206/bdac3d49/attachment-0001.html>


More information about the Mercurial-patches mailing list