[PATCH] subrepo: better error messages in _ensuregit

Mason Malone mason.malone at gmail.com
Mon Jan 18 00:35:00 UTC 2016


# HG changeset patch
# User Mason Malone <mason.malone at gmail.com>
# Date 1453076323 18000
#      Sun Jan 17 19:18:43 2016 -0500
# Node ID d229cd752f11065ca30264b451138456f747bee1
# Parent  add2ba16430ea5d31ee26e84e1b4c66dc3a6ee15
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.

diff -r add2ba16430e -r d229cd752f11 mercurial/subrepo.py
--- a/mercurial/subrepo.py	Fri Jan 15 13:14:49 2016 -0800
+++ b/mercurial/subrepo.py	Sun Jan 17 19:18:43 2016 -0500
@@ -1294,10 +1294,27 @@
             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'])
+            generic_error = _("error executing git for subrepo '%s': %s")
+            if e.errno != errno.ENOENT:
+                raise error.Abort(generic_error % (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(_("could not find git executable "
+                            "for subrepo '%s'. Tried both 'git' and 'git.cmd'."
+                            " If you've installed git already, you likely need"
+                            " to set the 'Path' system variable to include "
+                            "the 'bin' subdirectory of where git is installed"
+                        ) % self._path)
+                    else:
+                        raise error.Abort(generic_error % (self._path,
+                            e2.strerror))
+            else:
+                raise error.Abort(_("could not find git executable for subrepo"
+                    " '%s'. Make sure 'git' is in your $PATH") % self._path)
         versionstatus = self._checkversion(out)
         if versionstatus == 'unknown':
             self.ui.warn(_('cannot retrieve git version\n'))


More information about the Mercurial-devel mailing list