D4707: localrepo: support shared repo creation

indygreg (Gregory Szorc) phabricator at mercurial-scm.org
Wed Sep 26 13:24:11 EDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rHG4ece3cdfd907: localrepo: support shared repo creation (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4707?vs=11315&id=11379

REVISION DETAIL
  https://phab.mercurial-scm.org/D4707

AFFECTED FILES
  mercurial/hg.py
  mercurial/localrepo.py
  tests/test-share.t

CHANGE DETAILS

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
 
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,15 +2782,30 @@
     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}
 
 def createrepository(ui, path, createopts=None):
     """Create a new repository in a vfs.
 
     ``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/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



To: indygreg, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list