subrepo: don't crash when git repo is missing stable
authorEric Eisner <ede@mit.edu>
Mon, 07 Mar 2011 12:03:54 -0500
branchstable
changeset 13553 dea6efdd7ec4
parent 13552 7ab85fec60c3
child 13557 7509e36eed3b
subrepo: don't crash when git repo is missing
mercurial/subrepo.py
tests/test-subrepo-git.t
--- a/mercurial/subrepo.py	Mon Mar 07 15:44:43 2011 -0600
+++ b/mercurial/subrepo.py	Mon Mar 07 12:03:54 2011 -0500
@@ -703,6 +703,9 @@
 
         return retdata, p.returncode
 
+    def _gitmissing(self):
+        return not os.path.exists(os.path.join(self._abspath, '.git'))
+
     def _gitstate(self):
         return self._gitcommand(['rev-parse', 'HEAD'])
 
@@ -759,7 +762,7 @@
         return _abssource(self)
 
     def _fetch(self, source, revision):
-        if not os.path.exists(os.path.join(self._abspath, '.git')):
+        if self._gitmissing():
             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
             self._gitnodir(['clone', self._abssource(source), self._abspath])
         if self._githavelocally(revision):
@@ -772,6 +775,8 @@
                                (revision, self._relpath))
 
     def dirty(self, ignoreupdate=False):
+        if self._gitmissing():
+            return True
         if not ignoreupdate and self._state[1] != self._gitstate():
             # different version checked out
             return True
@@ -860,6 +865,8 @@
             rawcheckout()
 
     def commit(self, text, user, date):
+        if self._gitmissing():
+            raise util.Abort(_("subrepo %s is missing") % self._relpath)
         cmd = ['commit', '-a', '-m', text]
         env = os.environ.copy()
         if user:
@@ -896,6 +903,8 @@
             mergefunc()
 
     def push(self, force):
+        if self._gitmissing():
+            raise util.Abort(_("subrepo %s is missing") % self._relpath)
         # if a branch in origin contains the revision, nothing to do
         branch2rev, rev2branch = self._gitbranchmap()
         if self._state[1] in rev2branch:
@@ -929,6 +938,8 @@
             return False
 
     def remove(self):
+        if self._gitmissing():
+            return
         if self.dirty():
             self._ui.warn(_('not removing repo %s because '
                             'it has changes.\n') % self._relpath)
@@ -972,6 +983,9 @@
 
 
     def status(self, rev2, **opts):
+        if self._gitmissing():
+            # if the repo is missing, return no results
+            return [], [], [], [], [], [], []
         rev1 = self._state[1]
         modified, added, removed = [], [], []
         if rev2:
--- a/tests/test-subrepo-git.t	Mon Mar 07 15:44:43 2011 -0600
+++ b/tests/test-subrepo-git.t	Mon Mar 07 12:03:54 2011 -0500
@@ -314,6 +314,26 @@
   cloning subrepo s
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+Don't crash if the subrepo is missing
+
+  $ hg clone t missing -q
+  $ cd missing
+  $ rm -rf s
+  $ hg status -S
+  $ hg sum | grep commit
+  commit: 1 subrepos
+  $ hg push -q
+  abort: subrepo s is missing
+  [255]
+  $ hg commit -qm missing
+  abort: subrepo s is missing
+  [255]
+  $ hg update -C
+  cloning subrepo s
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg sum | grep commit
+  commit: (clean)
+
 Check hg update --clean
   $ cd $TESTTMP/ta
   $ echo  > s/g