mirror of
https://github.com/facebook/sapling.git
synced 2024-12-27 06:52:23 +03:00
repo: skip data migrations if repo lock cannot be taken
Summary: This avoids deadlock with edenfs-triggered debugimporthelper. Reviewed By: simpkins Differential Revision: D20270678 fbshipit-source-id: 6d3e7664b375d10ad2a8caeecaef5fa895264472
This commit is contained in:
parent
9e87cf0897
commit
3e80ba4f99
@ -579,6 +579,16 @@ class localrepository(object):
|
|||||||
# generic mapping between names and nodes
|
# generic mapping between names and nodes
|
||||||
self.names = namespaces.namespaces(self)
|
self.names = namespaces.namespaces(self)
|
||||||
|
|
||||||
|
self._eventreporting = True
|
||||||
|
try:
|
||||||
|
self._svfsmigration()
|
||||||
|
self._narrowheadsmigration()
|
||||||
|
self._zstorecommitdatamigration()
|
||||||
|
except errormod.LockHeld:
|
||||||
|
# Not fatal.
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _svfsmigration(self):
|
||||||
# Migrate 'remotenames' and 'bookmarks' state from sharedvfs to
|
# Migrate 'remotenames' and 'bookmarks' state from sharedvfs to
|
||||||
# storevfs.
|
# storevfs.
|
||||||
# This cannot be safely done in the remotenames extension because
|
# This cannot be safely done in the remotenames extension because
|
||||||
@ -586,15 +596,11 @@ class localrepository(object):
|
|||||||
# use changelog before 'remotenames.reposetup'.
|
# use changelog before 'remotenames.reposetup'.
|
||||||
for name in ["remotenames", "bookmarks"]:
|
for name in ["remotenames", "bookmarks"]:
|
||||||
if self.sharedvfs.exists(name) and not os.path.exists(self.svfs.join(name)):
|
if self.sharedvfs.exists(name) and not os.path.exists(self.svfs.join(name)):
|
||||||
with self.wlock(), self.lock():
|
with self.wlock(wait=False), self.lock(wait=False):
|
||||||
data = self.sharedvfs.read(name)
|
data = self.sharedvfs.read(name)
|
||||||
# avoid svfs.write so it does not write into metalog.
|
# avoid svfs.write so it does not write into metalog.
|
||||||
util.writefile(self.svfs.join(name), data)
|
util.writefile(self.svfs.join(name), data)
|
||||||
|
|
||||||
self._narrowheadsmigration()
|
|
||||||
self._zstorecommitdatamigration()
|
|
||||||
self._eventreporting = True
|
|
||||||
|
|
||||||
def _narrowheadsmigration(self):
|
def _narrowheadsmigration(self):
|
||||||
"""Migrate if 'narrow-heads' config has changed."""
|
"""Migrate if 'narrow-heads' config has changed."""
|
||||||
narrowheadsdesired = self.ui.configbool("experimental", "narrow-heads")
|
narrowheadsdesired = self.ui.configbool("experimental", "narrow-heads")
|
||||||
@ -613,13 +619,13 @@ class localrepository(object):
|
|||||||
if narrowheadsdesired != narrowheadscurrent:
|
if narrowheadsdesired != narrowheadscurrent:
|
||||||
if narrowheadsdesired:
|
if narrowheadsdesired:
|
||||||
# Migrating up is easy: Just add the requirement.
|
# Migrating up is easy: Just add the requirement.
|
||||||
self.ui.write_err(
|
with self.lock(wait=False):
|
||||||
_(
|
self.ui.write_err(
|
||||||
"migrating repo to new-style visibility and phases\n"
|
_(
|
||||||
"(this does not affect most workflows; post in Source Control @ FB if you have issues)\n"
|
"migrating repo to new-style visibility and phases\n"
|
||||||
|
"(this does not affect most workflows; post in Source Control @ FB if you have issues)\n"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
with self.lock():
|
|
||||||
self.storerequirements.add("narrowheads")
|
self.storerequirements.add("narrowheads")
|
||||||
self._writestorerequirements()
|
self._writestorerequirements()
|
||||||
else:
|
else:
|
||||||
@ -627,14 +633,14 @@ class localrepository(object):
|
|||||||
# For this invocation, still pretend that we use narrow-heads.
|
# For this invocation, still pretend that we use narrow-heads.
|
||||||
# But the next invocation will use non-narrow-heads.
|
# But the next invocation will use non-narrow-heads.
|
||||||
self.ui.setconfig("experimental", "narrow-heads", True)
|
self.ui.setconfig("experimental", "narrow-heads", True)
|
||||||
# Writing to <shared repo path>/.hg/phaseroots
|
with self.lock(wait=False):
|
||||||
self.ui.write_err(
|
# Writing to <shared repo path>/.hg/phaseroots
|
||||||
_(
|
self.ui.write_err(
|
||||||
"migrating repo to old-style visibility and phases\n"
|
_(
|
||||||
"(this restores the behavior to a known good state; post in Source Control @ FB if you have issues)\n"
|
"migrating repo to old-style visibility and phases\n"
|
||||||
|
"(this restores the behavior to a known good state; post in Source Control @ FB if you have issues)\n"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
with self.lock():
|
|
||||||
# Accessing the raw file directly without going through
|
# Accessing the raw file directly without going through
|
||||||
# complicated phasescache APIs.
|
# complicated phasescache APIs.
|
||||||
draftroots = self.nodes("roots(draft())")
|
draftroots = self.nodes("roots(draft())")
|
||||||
@ -668,13 +674,13 @@ class localrepository(object):
|
|||||||
if zstorecommitdatadesired:
|
if zstorecommitdatadesired:
|
||||||
# Migrating up. Read all commits in revlog and store them in
|
# Migrating up. Read all commits in revlog and store them in
|
||||||
# zstore.
|
# zstore.
|
||||||
with self.lock():
|
with self.lock(wait=False):
|
||||||
self._syncrevlogtozstore()
|
self._syncrevlogtozstore()
|
||||||
self.storerequirements.add("zstorecommitdata")
|
self.storerequirements.add("zstorecommitdata")
|
||||||
self._writestorerequirements()
|
self._writestorerequirements()
|
||||||
else:
|
else:
|
||||||
# Migrating down is just removing the store requirement.
|
# Migrating down is just removing the store requirement.
|
||||||
with self.lock():
|
with self.lock(wait=False):
|
||||||
self.storerequirements.remove("zstorecommitdata")
|
self.storerequirements.remove("zstorecommitdata")
|
||||||
self._writestorerequirements()
|
self._writestorerequirements()
|
||||||
|
|
||||||
|
@ -302,6 +302,15 @@ class lock(object):
|
|||||||
return
|
return
|
||||||
assert self._lockfd is None
|
assert self._lockfd is None
|
||||||
retry = 5
|
retry = 5
|
||||||
|
|
||||||
|
path = self.vfs.join(self.f)
|
||||||
|
if (
|
||||||
|
util.istest()
|
||||||
|
and self.f
|
||||||
|
in encoding.environ.get("EDENSCM_TEST_PRETEND_LOCKED", "").split()
|
||||||
|
):
|
||||||
|
raise error.LockHeld(errno.EAGAIN, path, self.desc, None)
|
||||||
|
|
||||||
while not self.held and retry:
|
while not self.held and retry:
|
||||||
retry -= 1
|
retry -= 1
|
||||||
try:
|
try:
|
||||||
|
@ -23,6 +23,11 @@ Make 'B' public, and 'C' draft.
|
|||||||
Migrate down.
|
Migrate down.
|
||||||
|
|
||||||
$ setconfig experimental.narrow-heads=false
|
$ setconfig experimental.narrow-heads=false
|
||||||
|
|
||||||
|
(Test if the repo is locked, the auto migration is skipped)
|
||||||
|
$ EDENSCM_TEST_PRETEND_LOCKED=lock hg phase $B
|
||||||
|
112478962961147124edd43549aedd1a335e44bf: public
|
||||||
|
|
||||||
$ hg phase $B
|
$ hg phase $B
|
||||||
migrating repo to old-style visibility and phases
|
migrating repo to old-style visibility and phases
|
||||||
(this restores the behavior to a known good state; post in Source Control @ FB if you have issues)
|
(this restores the behavior to a known good state; post in Source Control @ FB if you have issues)
|
||||||
|
Loading…
Reference in New Issue
Block a user