diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -49,10 +49,6 @@ vfs as vfsmod, ) -from .utils import ( - stringutil, -) - release = lock.release # shared features @@ -261,44 +257,13 @@ rev, checkout = addbranchrevs(srcrepo, srcrepo, branches, None) else: srcrepo = source.local() - origsource = source = srcrepo.url() checkout = None - sharedpath = srcrepo.sharedpath # if our source is already sharing - - destwvfs = vfsmod.vfs(dest, realpath=True) - destvfs = vfsmod.vfs(os.path.join(destwvfs.base, '.hg'), realpath=True) - - if destvfs.lexists(): - raise error.Abort(_('destination already exists')) - - if not destwvfs.isdir(): - destwvfs.makedirs() - destvfs.makedir() + r = repository(ui, dest, create=True, createopts={ + 'sharedrepo': srcrepo, + 'sharedrelative': relative, + }) - requirements = '' - try: - requirements = srcrepo.vfs.read('requires') - except IOError as inst: - if inst.errno != errno.ENOENT: - raise - - if relative: - try: - sharedpath = os.path.relpath(sharedpath, destvfs.base) - requirements += 'relshared\n' - except (IOError, ValueError) as e: - # ValueError is raised on Windows if the drive letters differ on - # each path - raise error.Abort(_('cannot calculate relative path'), - hint=stringutil.forcebytestr(e)) - else: - requirements += 'shared\n' - - destvfs.write('requires', requirements) - destvfs.write('sharedpath', sharedpath) - - r = repository(ui, destwvfs.base) postshare(srcrepo, r, bookmarks=bookmarks, defaultpath=defaultpath) _postshareupdate(r, update, checkout=checkout) return r diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -2714,6 +2714,17 @@ """ createopts = createopts or {} + # If the repo is being created from a shared repository, we copy + # its requirements. + if 'sharedrepo' in createopts: + requirements = set(createopts['sharedrepo'].requirements) + if createopts.get('sharedrelative'): + requirements.add('relshared') + else: + requirements.add('shared') + + return requirements + requirements = {'revlogv1'} if ui.configbool('format', 'usestore'): requirements.add('store') @@ -2771,7 +2782,11 @@ Extensions can wrap this function to filter out creation options they know how to handle. """ - known = {'narrowfiles'} + known = { + 'narrowfiles', + 'sharedrepo', + 'sharedrelative', + } return {k: v for k, v in createopts.items() if k not in known} @@ -2780,6 +2795,17 @@ ``path`` path to the new repo's working directory. ``createopts`` options for the new repository. + + The following keys for ``createopts`` are recognized: + + narrowfiles + Set up repository to support narrow file storage. + sharedrepo + Repository object from which storage should be shared. + sharedrelative + Boolean indicating if the path to the shared repo should be + stored as relative. By default, the pointer to the "parent" repo + is stored as an absolute path. """ createopts = createopts or {} @@ -2803,12 +2829,24 @@ if hgvfs.exists(): raise error.RepoError(_('repository %s already exists') % path) + if 'sharedrepo' in createopts: + sharedpath = createopts['sharedrepo'].sharedpath + + if createopts.get('sharedrelative'): + try: + sharedpath = os.path.relpath(sharedpath, hgvfs.base) + except (IOError, ValueError) as e: + # ValueError is raised on Windows if the drive letters differ + # on each path. + raise error.Abort(_('cannot calculate relative path'), + hint=stringutil.forcebytestr(e)) + if not wdirvfs.exists(): wdirvfs.makedirs() hgvfs.makedir(notindexed=True) - if b'store' in requirements: + if b'store' in requirements and 'sharedrepo' not in createopts: hgvfs.mkdir(b'store') # We create an invalid changelog outside the store so very old @@ -2825,6 +2863,10 @@ scmutil.writerequires(hgvfs, requirements) + # Write out file telling readers where to find the shared store. + if 'sharedrepo' in createopts: + hgvfs.write(b'sharedpath', sharedpath) + def poisonrepository(repo): """Poison a repository instance so it can no longer be used.""" # Perform any cleanup on the instance. diff --git a/tests/test-share.t b/tests/test-share.t --- a/tests/test-share.t +++ b/tests/test-share.t @@ -399,8 +399,8 @@ ../../orig/.hg (no-eol) $ grep shared thisdir/*/.hg/requires thisdir/abs/.hg/requires:shared + thisdir/rel/.hg/requires:relshared thisdir/rel/.hg/requires:shared - thisdir/rel/.hg/requires:relshared test that relative shared paths aren't relative to $PWD