changeset 27935:594bdc380aa2 stable

subrepo: better error messages in _ensuregit This patch improves the error messages raised when an OSError occurs, since simply re-raising the exception can be both confusing and misleading. For example, if "hg identify" is run inside a repository that contains a Git subrepository and the git binary could not be found, it'll exit with the message "abort: No such file or directory". That implies "identify" has a problem reading the repository itself. There's no way for the user to know what the real problem is unless they dive into the Mercurial source, which is what I ended up doing after spending hours debugging errors while provisioning a VM with Ansible (turns out I forgot to install Git on it). Descriptive errors are especially important on Windows, since it's common for Windows users to forget to set the "Path" system variable after installing Git.
author Mason Malone <mason.malone@gmail.com>
date Sun, 17 Jan 2016 22:53:57 -0500
parents 1779ff7426c9
children fedd81659643
files mercurial/subrepo.py
diffstat 1 files changed, 19 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/subrepo.py	Sat Jan 23 17:31:31 2016 +0800
+++ b/mercurial/subrepo.py	Sun Jan 17 22:53:57 2016 -0500
@@ -1294,10 +1294,25 @@
             self._gitexecutable = 'git'
             out, err = self._gitnodir(['--version'])
         except OSError as e:
-            if e.errno != 2 or os.name != 'nt':
-                raise
-            self._gitexecutable = 'git.cmd'
-            out, err = self._gitnodir(['--version'])
+            genericerror = _("error executing git for subrepo '%s': %s")
+            notfoundhint = _("check git is installed and in your PATH")
+            if e.errno != errno.ENOENT:
+                raise error.Abort(genericerror % (self._path, e.strerror))
+            elif os.name == 'nt':
+                try:
+                    self._gitexecutable = 'git.cmd'
+                    out, err = self._gitnodir(['--version'])
+                except OSError as e2:
+                    if e2.errno == errno.ENOENT:
+                        raise error.Abort(_("couldn't find 'git' or 'git.cmd'"
+                            " for subrepo '%s'") % self._path,
+                            hint=notfoundhint)
+                    else:
+                        raise error.Abort(genericerror % (self._path,
+                            e2.strerror))
+            else:
+                raise error.Abort(_("couldn't find git for subrepo '%s'")
+                    % self._path, hint=notfoundhint)
         versionstatus = self._checkversion(out)
         if versionstatus == 'unknown':
             self.ui.warn(_('cannot retrieve git version\n'))