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
next prev parent 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).