subrepo: implement 'unshare' for Mercurial subrepos
I think there's a slight hole here in that a subrepo could be shared, removed
from .hgsub, and then it's not part of context.substate (so not iterated over).
But the push command has the same hole IIRC, and I think removing a subrepo is
an edge case.
The import hack is a copy/paste of subrepo.subrepo().
--- a/mercurial/hg.py Tue Oct 17 21:48:56 2017 -0400
+++ b/mercurial/hg.py Tue Oct 17 22:55:33 2017 -0400
@@ -286,6 +286,13 @@
# update store, spath, svfs and sjoin of repo
repo.unfiltered().__init__(repo.baseui, repo.root)
+ # TODO: figure out how to access subrepos that exist, but were previously
+ # removed from .hgsub
+ c = repo['.']
+ subs = c.substate
+ for s in sorted(subs):
+ c.sub(s).unshare()
+
def postshare(sourcerepo, destrepo, bookmarks=True, defaultpath=None):
"""Called after a new shared repo is created.
--- a/mercurial/subrepo.py Tue Oct 17 21:48:56 2017 -0400
+++ b/mercurial/subrepo.py Tue Oct 17 22:55:33 2017 -0400
@@ -621,6 +621,11 @@
def shortid(self, revid):
return revid
+ def unshare(self):
+ '''
+ convert this repository from shared to normal storage.
+ '''
+
def verify(self):
'''verify the integrity of the repository. Return 0 on success or
warning, 1 on any error.
@@ -1083,6 +1088,24 @@
def shortid(self, revid):
return revid[:12]
+ @annotatesubrepoerror
+ def unshare(self):
+ # subrepo inherently violates our import layering rules
+ # because it wants to make repo objects from deep inside the stack
+ # so we manually delay the circular imports to not break
+ # scripts that don't use our demand-loading
+ global hg
+ from . import hg as h
+ hg = h
+
+ # Nothing prevents a user from sharing in a repo, and then making that a
+ # subrepo. Alternately, the previous unshare attempt may have failed
+ # part way through. So recurse whether or not this layer is shared.
+ if self._repo.shared():
+ self.ui.status(_("unsharing subrepo '%s'\n") % self._relpath)
+
+ hg.unshare(self.ui, self._repo)
+
def verify(self):
try:
rev = self._state[1]
--- a/tests/test-archive.t Tue Oct 17 21:48:56 2017 -0400
+++ b/tests/test-archive.t Tue Oct 17 22:55:33 2017 -0400
@@ -51,6 +51,24 @@
$ hg -R clone1 update -C tip
cloning subrepo subrepo from $TESTTMP/test/subrepo
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ find share2 | egrep 'sharedpath|00.+\.i' | sort
+ share2/.hg/sharedpath
+ share2/subrepo/.hg/sharedpath
+ $ hg -R share2 unshare
+ unsharing subrepo 'subrepo'
+ $ find share2 | egrep 'sharedpath|00.+\.i' | sort
+ share2/.hg/00changelog.i
+ share2/.hg/sharedpath.old
+ share2/.hg/store/00changelog.i
+ share2/.hg/store/00manifest.i
+ share2/subrepo/.hg/00changelog.i
+ share2/subrepo/.hg/sharedpath.old
+ share2/subrepo/.hg/store/00changelog.i
+ share2/subrepo/.hg/store/00manifest.i
+ $ hg -R share2/subrepo log -r tip -T compact
+ 1[tip] 559dcc9bfa65 1970-01-01 00:00 +0000 test
+ subrepo mod
+
$ rm -rf clone1
$ hg clone -qr 1 test clone1