# HG changeset patch
# User Patrick Mezard <pmezard@gmail.com>
# Date 2010-11-18 22:05:10
# Node ID d0e21c5fde41c6a99aaaee07dbd6aae510b61da7
# Parent  82ca0c43bc44563a5fb3abb074ab7078bf366da6

subrepo: handle missing subrepo spec file as removed

Otherwise, all commands involving a dirstate walk will abort when trying to
readone of them. Deleting .hgsub basically breaks a repository.

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -21,7 +21,15 @@ def state(ctx, ui):
     p = config.config()
     def read(f, sections=None, remap=None):
         if f in ctx:
-            p.parse(f, ctx[f].data(), sections, remap, read)
+            try:
+                data = ctx[f].data()
+            except IOError, err:
+                if err.errno != errno.ENOENT:
+                    raise
+                # handle missing subrepo spec files as removed
+                ui.warn(_("warning: subrepo spec file %s not found\n") % f)
+                return
+            p.parse(f, data, sections, remap, read)
         else:
             raise util.Abort(_("subrepo spec file %s not found") % f)
 
diff --git a/tests/test-subrepo-missing.t b/tests/test-subrepo-missing.t
new file mode 100644
--- /dev/null
+++ b/tests/test-subrepo-missing.t
@@ -0,0 +1,51 @@
+  $ hg init repo
+  $ cd repo
+  $ hg init subrepo
+  $ echo a > subrepo/a
+  $ hg -R subrepo ci -Am adda
+  adding a
+  $ echo 'subrepo = subrepo' > .hgsub
+  $ hg ci -Am addsubrepo
+  adding .hgsub
+  committing subrepository subrepo
+  $ echo b > subrepo/b
+  $ hg -R subrepo ci -Am addb
+  adding b
+  $ hg ci -m updatedsub
+  committing subrepository subrepo
+
+delete .hgsub and revert it
+
+  $ rm .hgsub
+  $ hg revert .hgsub
+  warning: subrepo spec file .hgsub not found
+
+delete .hgsubstate and revert it
+
+  $ rm .hgsubstate
+  $ hg revert .hgsubstate
+
+delete .hgsub and update
+
+  $ rm .hgsub
+  $ hg up 0
+  warning: subrepo spec file .hgsub not found
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg st
+  ! .hgsub
+  $ ls subrepo
+  a
+
+delete .hgsubstate and update
+
+  $ hg up -C
+  warning: subrepo spec file .hgsub not found
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ rm .hgsubstate
+  $ hg up 0  
+  remote changed .hgsubstate which local deleted
+  use (c)hanged version or leave (d)eleted? c
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg st
+  $ ls subrepo
+  a