Patchwork [2,of,2] subrepo: implement 'unshare' for Mercurial subrepos

login
register
mail settings
Submitter Matt Harbison
Date Oct. 18, 2017, 4:12 a.m.
Message ID <609c60c0b706f9b6402d.1508299959@Envy>
Download mbox | patch
Permalink /patch/25152/
State Accepted
Headers show

Comments

Matt Harbison - Oct. 18, 2017, 4:12 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1508295333 14400
#      Tue Oct 17 22:55:33 2017 -0400
# Node ID 609c60c0b706f9b6402d275a57b8255b142e8ba7
# Parent  a6b470f15cc5f902afd54f29b0e53e5c03f6eec6
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().
Augie Fackler - Oct. 18, 2017, 7:21 p.m.
On Wed, Oct 18, 2017 at 12:12:39AM -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1508295333 14400
> #      Tue Oct 17 22:55:33 2017 -0400
> # Node ID 609c60c0b706f9b6402d275a57b8255b142e8ba7
> # Parent  a6b470f15cc5f902afd54f29b0e53e5c03f6eec6
> subrepo: implement 'unshare' for Mercurial subrepos

queued, thanks

Patch

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -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.
 
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -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]
diff --git a/tests/test-archive.t b/tests/test-archive.t
--- a/tests/test-archive.t
+++ b/tests/test-archive.t
@@ -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