in eden/scm/edenscm/mercurial/localrepo.py [0:0]
def __init__(self, baseui, path, create=False):
if create and baseui.configbool("init", "use-rust"):
bindings.repo.repo.initialize(path, baseui._rcfg._rcfg)
create = False
self._containscount = 0
self.requirements = set()
self.storerequirements = set()
# wvfs: rooted at the repository root, used to access the working copy
self.wvfs = vfsmod.vfs(path, expandpath=True, realpath=True, cacheaudited=False)
# localvfs: rooted at .hg, used to access repo files outside of
# the store that are local to this working copy.
self.localvfs = None
# sharedvfs: the local vfs of the primary shared repo for shared repos.
# for non-shared repos this is the same as localvfs.
self.sharedvfs = None
# svfs: store vfs - usually rooted at .hg/store, used to access repository history
# If this is a shared repository, this vfs may point to another
# repository's .hg/store directory.
self.svfs = None
self.root = self.wvfs.base
self.path = self.wvfs.join(".hg")
self.origroot = path
# This is only used by context.workingctx.match in order to
# detect files in forbidden paths.
self.auditor = pathutil.pathauditor(self.root)
# This is only used by context.basectx.match in order to detect
# files in forbidden paths..
self.nofsauditor = pathutil.pathauditor(self.root, realfs=False, cached=True)
self.baseui = baseui
self.ui = baseui.copy()
self.localvfs = vfsmod.vfs(self.path, cacheaudited=True)
if self.ui.configbool("devel", "all-warnings") or self.ui.configbool(
"devel", "check-locks"
):
self.localvfs.audit = self._getvfsward(self.localvfs.audit)
# A list of callback to shape the phase if no data were found.
# Callback are in the form: func(repo, roots) --> processed root.
# This list it to be filled by extension during repo setup
self._phasedefaults = []
# Create the initial directory if it doesn't already exist.
created = False
if not self.localvfs.isdir():
if create:
created = True
# Create initial directory. Just enough to allow basic config
# loading.
if not self.wvfs.exists():
self.wvfs.makedirs()
self.localvfs.makedir(notindexed=True)
else:
raise errormod.RepoError(_("repository %s not found") % path)
elif create:
raise errormod.RepoError(_("repository %s already exists") % path)
# Prepare .hg/reponame in localvfs before calling into dynamicconfig.
if created:
reponame = self.ui.config("remotefilelog", "reponame")
if reponame and not self.localvfs.exists("reponame"):
self.localvfs.writeutf8("reponame", reponame.strip())
self.ui.reloadconfigs(self.root)
# Setting the inner Rust repo should only be done when the filesystem actually exists
if self.ui.configbool("init", "use-rust"):
self._rsrepo = bindings.repo.repo(self.root)
self._loadextensions()
cacheaudited = self.ui.configbool("unsafe", "wvfsauditorcache")
self.wvfs.audit._cached = cacheaudited
self.supported = self._featuresetup(self.featuresetupfuncs, self._basesupported)
self.storesupported = self._featuresetup(
self.storefeaturesetupfuncs, self._basestoresupported
)
color.setup(self.ui)
# Add compression engines.
for name in util.compengines:
engine = util.compengines[name]
if engine.revlogheader():
self.supported.add("exp-compression-%s" % name)
if created:
self.requirements = newreporequirements(self)
if "store" in self.requirements:
self.storerequirements = newrepostorerequirements(self)
self.localvfs.mkdir("store")
# create an invalid changelog
self.localvfs.append(
"00changelog.i",
b"\0\0\0\1"
b" dummy changelog to prevent using the old repo layout",
)
else:
try:
self.requirements = scmutil.readrequires(self.localvfs, self.supported)
except IOError as inst:
if inst.errno != errno.ENOENT:
raise
cachepath = self.localvfs.join("cache")
self.sharedpath = self.path
self.sharedroot = self.root
try:
sharedpath = self.localvfs.readutf8("sharedpath").rstrip("\n")
if "relshared" in self.requirements:
sharedpath = self.localvfs.join(sharedpath)
sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
cachepath = sharedvfs.join("cache")
s = sharedvfs.base
if not sharedvfs.exists():
raise errormod.RepoError(
_(".hg/sharedpath points to nonexistent directory %s") % s
)
self.sharedpath = s
self.sharedroot = sharedvfs.dirname(s)
self.sharedvfs = sharedvfs
# Read the requirements of the shared repo to make sure we
# support them.
try:
scmutil.readrequires(self.sharedvfs, self.supported)
except IOError as inst:
if inst.errno != errno.ENOENT:
raise
self.sharedvfs.audit = self._getvfsward(self.sharedvfs.audit)
except IOError as inst:
if inst.errno != errno.ENOENT:
raise
self.sharedvfs = self.localvfs
# If this is a new repo, generate the dynamic configs. We must do this
# after the sharedvfs is set up so we can generate the dynamic config in
# the shared vfs.
if created:
self.ui.reloadconfigs(self.root)
self.store = store.store(
self.requirements,
self.sharedpath,
lambda base: vfsmod.vfs(base, cacheaudited=True),
self.ui.uiconfig(),
)
self.spath = self.store.path
self.svfs = self.store.vfs
self.sjoin = self.store.join
store.setvfsmode(self.localvfs)
store.setvfsmode(self.sharedvfs)
self.cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
store.setvfsmode(self.cachevfs)
if self.ui.configbool("devel", "all-warnings") or self.ui.configbool(
"devel", "check-locks"
):
if util.safehasattr(self.svfs, "vfs"): # this is filtervfs
self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
else: # standard vfs
self.svfs.audit = self._getsvfsward(self.svfs.audit)
if not create and "store" in self.requirements:
try:
self.storerequirements = scmutil.readrequires(
self.svfs, self.storesupported
)
except IOError as inst:
if inst.errno != errno.ENOENT:
raise
if create:
self._writerequirements()
self._writestorerequirements()
if "hgsql" in self.requirements:
# hgsql wants raw access to revlog. Disable modern features
# unconditionally for hgsql.
self.ui.setconfig("experimental", "evolution", "obsolete", "hgsql")
self.ui.setconfig("experimental", "narrow-heads", "false", "hgsql")
self.ui.setconfig("experimental", "rust-commits", "false", "hgsql")
self.ui.setconfig("visibility", "enabled", "false", "hgsql")
self._dirstatevalidatewarned = False
self._branchcaches = {}
self.filterpats = {}
self._datafilters = {}
self._transref = self._lockref = self._wlockref = None
# headcache might belong to the changelog object for easier
# invalidation. However, that requires moving the dependencies
# involved in `head` calculation to changelog too, including
# remotenames.
self._headcache = {}
self.connectionpool = connectionpool.connectionpool(self)
self._smallcommitmetadata = None
# A cache for various files under .hg/ that tracks file changes,
# (used by the filecache decorator)
#
# Maps a property name to its util.filecacheentry
self._filecache = {}
# post-dirstate-status hooks
self._postdsstatus = []
# generic mapping between names and nodes
self.names = namespaces.namespaces(self)
# whether the repo is changed (by transaction).
# currently used to decide whether to run fsync.
self._txnreleased = False
self._applyopenerreqs()
self._eventreporting = True
try:
self._treestatemigration()
self._visibilitymigration()
self._svfsmigration()
self._narrowheadsmigration()
except errormod.LockHeld:
self.ui.debug("skipping automigrate because lock is held\n")
except errormod.AbandonedTransactionFoundError:
self.ui.debug("skipping automigrate due to an abandoned transaction\n")