git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: Michael Schubert <mschub@elegosoft.com>
Cc: git@vger.kernel.org, Alex Vandiver <alex@chmrr.net>
Subject: Re: Doesn't disambiguate between 'external command failed' and 'command not found'
Date: Tue, 5 Jul 2011 19:16:05 -0400	[thread overview]
Message-ID: <20110705231604.GC12085@sigill.intra.peff.net> (raw)
In-Reply-To: <4E137701.1020007@elegosoft.com>

On Tue, Jul 05, 2011 at 10:41:37PM +0200, Michael Schubert wrote:

> Subject: [PATCH] help_unknown_cmd: do not propose an "unknown" cmd
> 
> When executing an external shell script like `git foo` with the following
> shebang "#!/usr/bin/not/existing", execvp returns 127 (ENOENT). Since
> help_unknown_cmd proposes the use of all external commands similar to
> the name of the "unknown" command, it suggests the just failed command
> again. Stop it.

Yeah, I don't think we can distinguish "not there" versus "bad
interpreter" just from the exec return. We would have to then search the
PATH to see if the file actually exists.

> -	if (SIMILAR_ENOUGH(best_similarity)) {
> +	if (n==1 && !strcmp(cmd, main_cmds.names[0]->name))
> +		;
> +		/*
> +		 * This avoids proposing the use of a command
> +		 * which apparently just didn't work, e.g.
> +		 * when executing a shell script git-foo with
> +		 * the following shebang:
> +		 *
> +		 * 	#!/usr/bin/not/here
> +		 *
> +		 */
> +	else if (SIMILAR_ENOUGH(best_similarity)) {

This misses the "autocorrect" case just above, which should not
autocorrect a command to itself (and I didn't try, but I assume it makes
more a really slow infinite loop).

So if you are going to follow this strategy, you are probably better to
just skip the entry (or give it a high levenshtein distance) in the main
loop where we calculate candidates.

But I wonder if we can do even better than just omitting it from the
candidates list. I mentioned searching the PATH above; but that is
exactly what load_command_list does to create this candidate list. So I
think the only way we can have an exact match is one of:

  1. There is a race condition. We tried to exec the command, and it was
     missing; meanwhile, another process created the command.

  2. Exec'ing the command returned ENOENT because of a bad interpreter.

Option (1) seems fairly unlikely; so maybe we should give the user some
advice about (2)?

Something like:

diff --git a/help.c b/help.c
index e925ca1..522b2ba 100644
--- a/help.c
+++ b/help.c
@@ -305,6 +305,10 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
 #define SIMILARITY_FLOOR 7
 #define SIMILAR_ENOUGH(x) ((x) < SIMILARITY_FLOOR)
 
+static const char bad_interpreter_advice[] =
+"'%s' appears to be a git command, but we were not able to\n"
+"execute it. Check the #!-line of the git-%s script.";
+
 const char *help_unknown_cmd(const char *cmd)
 {
 	int i, n, best_similarity = 0;
@@ -329,6 +333,14 @@ const char *help_unknown_cmd(const char *cmd)
 		int cmp = 0; /* avoid compiler stupidity */
 		const char *candidate = main_cmds.names[i]->name;
 
+		/*
+		 * An exact match means we have the command, but
+		 * for some reason exec'ing it gave us ENOENT; probably
+		 * it's a bad interpreter in the #! line.
+		 */
+		if (!strcmp(candidate, cmd))
+			die(bad_interpreter_advice, cmd, cmd);
+
 		/* Does the candidate appear in common_cmds list? */
 		while (n < ARRAY_SIZE(common_cmds) &&
 		       (cmp = strcmp(common_cmds[n].name, candidate)) < 0)

I'm not all that happy with the advice, though. It's pretty technical
and specific. I'm not sure whether it would be helpful to most users or
not.

-Peff

  reply	other threads:[~2011-07-05 23:16 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-05 16:49 Doesn't disambiguate between 'external command failed' and 'command not found' Alex Vandiver
2011-07-05 20:41 ` Michael Schubert
2011-07-05 23:16   ` Jeff King [this message]
2011-07-05 23:22     ` Jeff King
2011-07-06 11:24       ` Sverre Rabbelier
2011-07-06 11:47     ` Michael Schubert
2011-07-06 17:58       ` Jeff King
2011-07-06 18:00         ` Jeff King
2011-07-06 23:25           ` Junio C Hamano
2011-07-08 10:08             ` Michael Schubert
2011-07-08 16:52               ` Junio C Hamano
2011-07-06 17:24     ` Junio C Hamano
2011-07-06 17:56       ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110705231604.GC12085@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=alex@chmrr.net \
    --cc=git@vger.kernel.org \
    --cc=mschub@elegosoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).