comparison mercurial/hg.py @ 48343:b74ee41addee stable

sparse: lock the store when updating requirements config Differential Revision: https://phab.mercurial-scm.org/D11817
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Mon, 29 Nov 2021 12:27:33 +0000
parents 7d1e60244561
children f98d4d0a299a 75fc2537d93c
comparison
equal deleted inserted replaced
48342:50330d481640 48343:b74ee41addee
10 10
11 import errno 11 import errno
12 import os 12 import os
13 import shutil 13 import shutil
14 import stat 14 import stat
15 import weakref
15 16
16 from .i18n import _ 17 from .i18n import _
17 from .node import ( 18 from .node import (
18 hex, 19 hex,
19 sha1nodeconstants, 20 sha1nodeconstants,
675 srcpeer = peer(ui, peeropts, source) 676 srcpeer = peer(ui, peeropts, source)
676 else: 677 else:
677 srcpeer = source.peer() # in case we were called with a localrepo 678 srcpeer = source.peer() # in case we were called with a localrepo
678 branches = (None, branch or []) 679 branches = (None, branch or [])
679 origsource = source = srcpeer.url() 680 origsource = source = srcpeer.url()
680 srclock = destlock = cleandir = None 681 srclock = destlock = destwlock = cleandir = None
681 destpeer = None 682 destpeer = None
682 try: 683 try:
683 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs) 684 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
684 685
685 if dest is None: 686 if dest is None:
863 ui, 864 ui,
864 destrootpath, 865 destrootpath,
865 requirements=dest_reqs, 866 requirements=dest_reqs,
866 ) 867 )
867 destrepo = localrepo.makelocalrepository(ui, destrootpath) 868 destrepo = localrepo.makelocalrepository(ui, destrootpath)
869
870 destwlock = destrepo.wlock()
868 destlock = destrepo.lock() 871 destlock = destrepo.lock()
869 from . import streamclone # avoid cycle 872 from . import streamclone # avoid cycle
870 873
871 streamclone.local_copy(srcrepo, destrepo) 874 streamclone.local_copy(srcrepo, destrepo)
872 875
873 # we need to re-init the repo after manually copying the data 876 # we need to re-init the repo after manually copying the data
874 # into it 877 # into it
875 destpeer = peer(srcrepo, peeropts, dest) 878 destpeer = peer(srcrepo, peeropts, dest)
879
880 # make the peer aware that is it already locked
881 #
882 # important:
883 #
884 # We still need to release that lock at the end of the function
885 destpeer.local()._lockref = weakref.ref(destlock)
886 destpeer.local()._wlockref = weakref.ref(destwlock)
887 # dirstate also needs to be copied because `_wlockref` has a reference
888 # to it: this dirstate is saved to disk when the wlock is released
889 destpeer.local().dirstate = destrepo.dirstate
890
876 srcrepo.hook( 891 srcrepo.hook(
877 b'outgoing', source=b'clone', node=srcrepo.nodeconstants.nullhex 892 b'outgoing', source=b'clone', node=srcrepo.nodeconstants.nullhex
878 ) 893 )
879 else: 894 else:
880 try: 895 try:
1038 _update(destrepo, uprev) 1053 _update(destrepo, uprev)
1039 if update in destrepo._bookmarks: 1054 if update in destrepo._bookmarks:
1040 bookmarks.activate(destrepo, update) 1055 bookmarks.activate(destrepo, update)
1041 if destlock is not None: 1056 if destlock is not None:
1042 release(destlock) 1057 release(destlock)
1058 if destwlock is not None:
1059 release(destlock)
1043 # here is a tiny windows were someone could end up writing the 1060 # here is a tiny windows were someone could end up writing the
1044 # repository before the cache are sure to be warm. This is "fine" 1061 # repository before the cache are sure to be warm. This is "fine"
1045 # as the only "bad" outcome would be some slowness. That potential 1062 # as the only "bad" outcome would be some slowness. That potential
1046 # slowness already affect reader. 1063 # slowness already affect reader.
1047 with destrepo.lock(): 1064 with destrepo.lock():
1048 destrepo.updatecaches(caches=repositorymod.CACHES_POST_CLONE) 1065 destrepo.updatecaches(caches=repositorymod.CACHES_POST_CLONE)
1049 finally: 1066 finally:
1050 release(srclock, destlock) 1067 release(srclock, destlock, destwlock)
1051 if cleandir is not None: 1068 if cleandir is not None:
1052 shutil.rmtree(cleandir, True) 1069 shutil.rmtree(cleandir, True)
1053 if srcpeer is not None: 1070 if srcpeer is not None:
1054 srcpeer.close() 1071 srcpeer.close()
1055 if destpeer and destpeer.local() is None: 1072 if destpeer and destpeer.local() is None: