[PATCH stable] subrepo: don't crash when git repo is missing

Eric Eisner ede at MIT.EDU
Mon Mar 7 11:04:19 CST 2011


# HG changeset patch
# User Eric Eisner <ede at mit.edu>
# Date 1299517434 18000
# Branch stable
# Node ID 52067fb0c59c7cb4ce069bdd103d80fa3a5f28d1
# Parent  4ec34de8bbb1e58eca9c52e141c212d58bad9ace
subrepo: don't crash when git repo is missing

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -703,6 +703,9 @@ class gitsubrepo(abstractsubrepo):
 
         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 @@ class gitsubrepo(abstractsubrepo):
         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 @@ class gitsubrepo(abstractsubrepo):
                                (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 @@ class gitsubrepo(abstractsubrepo):
             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 @@ class gitsubrepo(abstractsubrepo):
             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 @@ class gitsubrepo(abstractsubrepo):
             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 @@ class gitsubrepo(abstractsubrepo):
 
 
     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:
diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t
--- a/tests/test-subrepo-git.t
+++ b/tests/test-subrepo-git.t
@@ -314,6 +314,26 @@ relative source expansion
   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


More information about the Mercurial-devel mailing list