git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] help.c: don't blame an user's typo when the system is at fault

From
Jeff King <peff@peff.net>
Date
Jul 20, 2009, 15:12 UTC
Message-ID
<20090720151217.GA5347@coredump.intra.peff.net>
In-Reply-To
<200907201617.48168.trast@student.ethz.ch>
On Mon, Jul 20, 2009 at 04:17:47PM +0200, Thomas Rast wrote:
Show 22 quoted lines
> The invocation of help_unknown_cmd comes from
> 
> 	while (1) {
> 		// ...
> 		was_alias = run_argv(&argc, &argv);
> 		if (errno != ENOENT)
> 			break;
> 		// ... side branch with an exit() ...
> 		if (!done_help) {
> 			cmd = argv[0] = help_unknown_cmd(cmd);
> 
> so errno is always ENOENT when help_unknown_cmd() is called.
> (Furthermore, the function itself uses git_config() and
> load_command_list(), both of which _probably_ clobber errno, I don't
> really have the time for an in-depth check.)
> 
> It also seems that the 'errno != ENOENT' check was intended to catch
> the case where the command failed for any reason other than that it
> does not exist, but this collides with the kernel reporting ENOENT if
> the _interpreter_ does not exist.  Perhaps run_argv should
> differentiate the case where a command executable exists but cannot be
> run?

Yes, I think double-checking the suggested commands list is only half of it; it still says "citool is not a git command" which is wrong. Getting it totally right means differentiating the two ENOENT cases, which I think would require searching the PATH.

Something like the patch below should work, though I didn't think terribly long about it, so there might be a corner case that isn't covered, or some easier helper functions for accomplishing this.

---
diff --git a/git.c b/git.c
index 5da6c65..4e44c98 100644
--- a/git.c
+++ b/git.c
@@ -3,6 +3,7 @@
 #include "cache.h"
 #include "quote.h"
 #include "run-command.h"
+#include "help.h"
 
 const char git_usage_string[] =
 	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
@@ -449,6 +450,16 @@ static int run_argv(int *argcp, const char ***argv)
 	return done_alias;
 }
 
+static int command_exists(const char *s)
+{
+	static struct cmdnames main_cmds, other_cmds;
+	static int loaded;
+	if (!loaded) {
+		load_command_list("git-", &main_cmds, &other_cmds);
+		loaded = 1;
+	}
+	return is_in_cmdlist(&main_cmds, s) || is_in_cmdlist(&other_cmds, s);
+}
 
 int main(int argc, const char **argv)
 {
@@ -504,7 +515,7 @@ int main(int argc, const char **argv)
 		static int done_help = 0;
 		static int was_alias = 0;
 		was_alias = run_argv(&argc, &argv);
-		if (errno != ENOENT)
+		if (errno != ENOENT || command_exists(argv[0]))
 			break;
 		if (was_alias) {
 			fprintf(stderr, "Expansion of alias '%s' failed; "
Previous: Thomas Rast
Message 4 of 4 in “Bad DWIM response when git gui cannot start”
  1. Peter KreftingJul 20, 2009
  2. help.c: don't blame an user's typo when the system is at faultMichele Ballabio, Jul 20, 2009
  3. Thomas RastJul 20, 2009
  4. Jeff KingJul 20, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.