Mercurial > hg
diff mercurial/localrepo.py @ 39697:98ca9078807a
localrepo: resolve store and cachevfs in makelocalrepository()
This is mostly a code move and refactor.
One change is that we now explicitly look for requirements indicating
a share is being used rather than blindly try to read from
.hg/sharedpath. Requirements *should* be all that is necessary to
dictate high-level behavior and I'm not sure why the previous code
was doing what it was.
The previous code has been in place since 87d1fd40f57e (authored in
2009). And the commit immediately after that (971e38a9344b) introduced
``hg.share()`` and always wrote the ``shared`` requirement. And as far
as I can tell, every revision of ``hg.share()`` since has written
either the ``shared`` or ``relshared`` requirement. So I'm pretty
sure we don't need to maintain BC by always looking for and honoring
the ``.hg/sharedpath`` file even if a requirement isn't present.
.. bc::
A repository will no longer use shared storage if it has a
``.hg/sharedpath`` file but no entry in ``.hg/requires`` saying it
is shared.
This change should not have any end-user impact, as all shared
repos should have a ``.hg/requires`` file indicating this.
Differential Revision: https://phab.mercurial-scm.org/D4573
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 12 Sep 2018 15:05:51 -0700 |
parents | 9de1a1c83cd7 |
children | f44187605315 |
line wrap: on
line diff
--- a/mercurial/localrepo.py Wed Sep 12 13:10:45 2018 -0700 +++ b/mercurial/localrepo.py Wed Sep 12 15:05:51 2018 -0700 @@ -56,7 +56,7 @@ revsetlang, scmutil, sparse, - store, + store as storemod, subrepoutil, tags as tagsmod, transaction, @@ -454,6 +454,40 @@ # At this point, we know we should be capable of opening the repository. # Now get on with doing that. + # The "store" part of the repository holds versioned data. How it is + # accessed is determined by various requirements. The ``shared`` or + # ``relshared`` requirements indicate the store lives in the path contained + # in the ``.hg/sharedpath`` file. This is an absolute path for + # ``shared`` and relative to ``.hg/`` for ``relshared``. + if b'shared' in requirements or b'relshared' in requirements: + sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n') + if b'relshared' in requirements: + sharedpath = hgvfs.join(sharedpath) + + sharedvfs = vfsmod.vfs(sharedpath, realpath=True) + + if not sharedvfs.exists(): + raise error.RepoError(_(b'.hg/sharedpath points to nonexistent ' + b'directory %s') % sharedvfs.base) + + storebasepath = sharedvfs.base + cachepath = sharedvfs.join(b'cache') + else: + storebasepath = hgvfs.base + cachepath = hgvfs.join(b'cache') + + # The store has changed over time and the exact layout is dictated by + # requirements. The store interface abstracts differences across all + # of them. + store = storemod.store(requirements, storebasepath, + lambda base: vfsmod.vfs(base, cacheaudited=True)) + + hgvfs.createmode = store.createmode + + # The cache vfs is used to manage cache files. + cachevfs = vfsmod.vfs(cachepath, cacheaudited=True) + cachevfs.createmode = store.createmode + return localrepository( baseui=baseui, ui=ui, @@ -462,6 +496,9 @@ hgvfs=hgvfs, requirements=requirements, supportedrequirements=supportedrequirements, + sharedpath=storebasepath, + store=store, + cachevfs=cachevfs, intents=intents) def gathersupportedrequirements(ui): @@ -581,7 +618,8 @@ } def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, - supportedrequirements, intents=None): + supportedrequirements, sharedpath, store, cachevfs, + intents=None): """Create a new local repository instance. Most callers should use ``hg.repository()``, ``localrepo.instance()``, @@ -612,6 +650,17 @@ ``set`` of bytestrings representing repository requirements that we know how to open. May be a supetset of ``requirements``. + sharedpath + ``bytes`` Defining path to storage base directory. Points to a + ``.hg/`` directory somewhere. + + store + ``store.basicstore`` (or derived) instance providing access to + versioned storage. + + cachevfs + ``vfs.vfs`` used for cache files. + intents ``set`` of system strings indicating what this repo will be used for. @@ -627,12 +676,11 @@ self.path = hgvfs.base self.requirements = requirements self.supported = supportedrequirements + self.sharedpath = sharedpath + self.store = store + self.cachevfs = cachevfs self.filtername = None - # svfs: 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 if (self.ui.configbool('devel', 'all-warnings') or self.ui.configbool('devel', 'check-locks')): @@ -644,32 +692,9 @@ color.setup(self.ui) - cachepath = self.vfs.join('cache') - self.sharedpath = self.path - try: - sharedpath = self.vfs.read("sharedpath").rstrip('\n') - if 'relshared' in self.requirements: - sharedpath = self.vfs.join(sharedpath) - vfs = vfsmod.vfs(sharedpath, realpath=True) - cachepath = vfs.join('cache') - s = vfs.base - if not vfs.exists(): - raise error.RepoError( - _('.hg/sharedpath points to nonexistent directory %s') % s) - self.sharedpath = s - except IOError as inst: - if inst.errno != errno.ENOENT: - raise - - self.store = store.store( - self.requirements, self.sharedpath, - lambda base: vfsmod.vfs(base, cacheaudited=True)) self.spath = self.store.path self.svfs = self.store.vfs self.sjoin = self.store.join - self.vfs.createmode = self.store.createmode - self.cachevfs = vfsmod.vfs(cachepath, cacheaudited=True) - self.cachevfs.createmode = self.store.createmode if (self.ui.configbool('devel', 'all-warnings') or self.ui.configbool('devel', 'check-locks')): if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs