diff mercurial/hg.py @ 52725:0f2268783c11

clone: explicitly steal lock instead of assigning previous lock The issue with reusing the lock from another repository is that various internal state are no longer correct, the main example of that is the dirstate, captured in the wlock to make sure it is written (when needed) on lock release. So instead, we create a proper lock from the repository, but "stealing" the on-disk lock from the previous object. This is a bit weird, but less than the previous situation.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 30 Jan 2025 09:23:16 +0100
parents 4cb75772818d
children
line wrap: on
line diff
--- a/mercurial/hg.py	Fri Dec 20 16:11:19 2024 +0100
+++ b/mercurial/hg.py	Thu Jan 30 09:23:16 2025 +0100
@@ -13,7 +13,6 @@
 import shutil
 import stat
 import typing
-import weakref
 
 from .i18n import _
 from .node import (
@@ -950,14 +949,16 @@
             # 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
+            if destrepo.dirstate._dirty:
+                msg = "dirstate dirty after stream clone"
+                raise error.ProgrammingError(msg)
+            destwlock = destpeer.local().wlock(steal_from=destwlock)
+            destlock = destpeer.local().lock(steal_from=destlock)
 
             srcrepo.hook(
-                b'outgoing', source=b'clone', node=srcrepo.nodeconstants.nullhex
+                b'outgoing',
+                source=b'clone',
+                node=srcrepo.nodeconstants.nullhex,
             )
         else:
             try:
@@ -1121,8 +1122,10 @@
                     bookmarks.activate(destrepo, update)
             if destlock is not None:
                 release(destlock)
+                destlock = None
             if destwlock is not None:
-                release(destlock)
+                release(destwlock)
+                destwlock = None
             # 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