diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -808,7 +808,7 @@ class gitsubrepo(abstractsubrepo): def dirty(self, ignoreupdate=False): if self._gitmissing(): - return True + return self._state[1] != '' if not ignoreupdate and self._state[1] != self._gitstate(): # different version checked out return True @@ -818,6 +818,9 @@ class gitsubrepo(abstractsubrepo): def get(self, state, overwrite=False): source, revision, kind = state + if not revision: + self.remove() + return self._fetch(source, revision) # if the repo was set to be bare, unbare it if self._gitcommand(['config', '--bool', 'core.bare']) == 'true': @@ -935,6 +938,8 @@ class gitsubrepo(abstractsubrepo): mergefunc() def push(self, force): + if not self._state[1]: + return True if self._gitmissing(): raise util.Abort(_("subrepo %s is missing") % self._relpath) # if a branch in origin contains the revision, nothing to do @@ -991,6 +996,8 @@ class gitsubrepo(abstractsubrepo): def archive(self, ui, archiver, prefix): source, revision = self._state + if not revision: + return self._fetch(source, revision) # Parse git's native archive command. @@ -1015,10 +1022,10 @@ class gitsubrepo(abstractsubrepo): def status(self, rev2, **opts): - if self._gitmissing(): + rev1 = self._state[1] + if self._gitmissing() or not rev1: # if the repo is missing, return no results return [], [], [], [], [], [], [] - rev1 = self._state[1] modified, added, removed = [], [], [] if rev2: command = ['diff-tree', rev1, 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 @@ -334,6 +334,33 @@ Don't crash if the subrepo is missing $ hg sum | grep commit commit: (clean) +Don't crash if the .hgsubstate entry is missing + + $ hg update 1 -q + $ hg rm .hgsubstate + $ hg commit .hgsubstate -m 'no substate' + created new head + $ hg tag -l nosubstate + $ hg manifest + .hgsub + a + + $ hg status -S + $ hg sum | grep commit + commit: 1 subrepos + + $ hg commit -m 'restore substate' + committing subrepository s + $ hg manifest + .hgsub + .hgsubstate + a + $ hg sum | grep commit + commit: (clean) + + $ hg update -qC nosubstate + $ ls s + Check hg update --clean $ cd $TESTTMP/ta $ echo > s/g