changeset 14536:52cbeb5a651b

subrepo: be more careful with deletions of .hgsub and .hgsubstate (issue2844) We shouldn't try to process subrepos if .hgsub isn't present and we should remove .hgsubstate if .hgsub is marked for removal.
author Matt Mackall <mpm@selenic.com>
date Mon, 06 Jun 2011 15:17:40 -0500
parents e597ef52a7c2
children 3c7907dc95ca
files mercurial/localrepo.py tests/test-subrepo.t
diffstat 2 files changed, 56 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Sun Jun 05 22:26:01 2011 +0200
+++ b/mercurial/localrepo.py	Mon Jun 06 15:17:40 2011 -0500
@@ -944,18 +944,28 @@
             # check subrepos
             subs = []
             removedsubs = set()
-            for p in wctx.parents():
-                removedsubs.update(s for s in p.substate if match(s))
-            for s in wctx.substate:
-                removedsubs.discard(s)
-                if match(s) and wctx.sub(s).dirty():
-                    subs.append(s)
-            if (subs or removedsubs):
-                if (not match('.hgsub') and
-                    '.hgsub' in (wctx.modified() + wctx.added())):
-                    raise util.Abort(_("can't commit subrepos without .hgsub"))
-                if '.hgsubstate' not in changes[0]:
-                    changes[0].insert(0, '.hgsubstate')
+            if '.hgsub' in wctx:
+                # only manage subrepos and .hgsubstate if .hgsub is present
+                for p in wctx.parents():
+                    removedsubs.update(s for s in p.substate if match(s))
+                for s in wctx.substate:
+                    removedsubs.discard(s)
+                    if match(s) and wctx.sub(s).dirty():
+                        subs.append(s)
+                if (subs or removedsubs):
+                    if (not match('.hgsub') and
+                        '.hgsub' in (wctx.modified() + wctx.added())):
+                        raise util.Abort(
+                            _("can't commit subrepos without .hgsub"))
+                    if '.hgsubstate' not in changes[0]:
+                        changes[0].insert(0, '.hgsubstate')
+                        if '.hgsubstate' in changes[2]:
+                            changes[2].remove('.hgsubstate')
+            elif '.hgsub' in changes[2]:
+                # clean up .hgsubstate when .hgsub is removed
+                if ('.hgsubstate' in wctx and
+                    '.hgsubstate' not in changes[0] + changes[1] + changes[2]):
+                    changes[2].insert(0, '.hgsubstate')
 
             if subs and not self.ui.configbool('ui', 'commitsubrepos', True):
                 changedsubs = [s for s in subs if wctx.sub(s).dirty(True)]
--- a/tests/test-subrepo.t	Sun Jun 05 22:26:01 2011 +0200
+++ b/tests/test-subrepo.t	Mon Jun 06 15:17:40 2011 -0500
@@ -500,6 +500,7 @@
   $ hg -R testdelete remove testdelete/.hgsub
   $ hg -R testdelete ci -m ".hgsub deleted"
   $ cat testdelete/.hgsubstate
+  bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
 
 test repository cloning
 
@@ -823,3 +824,36 @@
   fc627a69481f
   $ hg -R t id 
   e95bcfa18a35
+
+Test that removing .hgsubstate doesn't break anything:
+
+  $ hg rm -f .hgsubstate
+  $ hg ci -mrm
+  committing subrepository s
+  committing subrepository t
+  created new head
+  $ hg log -vr tip
+  changeset:   14:3941e0aa5236
+  tag:         tip
+  parent:      11:365661e5936a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  description:
+  rm
+  
+  
+
+Test that removing .hgsub removes .hgsubstate:
+
+  $ hg rm .hgsub
+  $ hg ci -mrm2
+  $ hg log -vr tip
+  changeset:   15:8b31de9d13d1
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files:       .hgsub .hgsubstate
+  description:
+  rm2
+  
+