Merge branch 'dd/help-autocorrect-never'

"git $cmd $args", when $cmd is not a recognised subcommand, by
default tries to see if $cmd is a typo of an existing subcommand
and optionally executes the corrected command if there is only one
possibility, depending on the setting of help.autocorrect; the
users can now disable the whole thing, including the cycles spent
to find a likely typo, by setting the configuration variable to
'never'.

* dd/help-autocorrect-never:
  help.c: help.autocorrect=never means "do not compute suggestions"
This commit is contained in:
Junio C Hamano 2020-12-14 10:21:36 -08:00
commit 78abcff222
3 changed files with 52 additions and 18 deletions

View File

@ -8,13 +8,14 @@ help.format::
the default. 'web' and 'html' are the same.
help.autoCorrect::
Automatically correct and execute mistyped commands after
waiting for the given number of deciseconds (0.1 sec). If more
than one command can be deduced from the entered text, nothing
will be executed. If the value of this option is negative,
the corrected command will be executed immediately. If the
value is 0 - the command will be just shown but not executed.
This is the default.
If git detects typos and can identify exactly one valid command similar
to the error, git will automatically run the intended command after
waiting a duration of time defined by this configuration value in
deciseconds (0.1 sec). If this value is 0, the suggested corrections
will be shown, but not executed. If it is a negative integer, or
"immediate", the suggested command
is run immediately. If "never", suggestions are not shown at all. The
default value is zero.
help.htmlPath::
Specify the path where the HTML documentation resides. File system paths

25
help.c
View File

@ -472,12 +472,26 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)
static int autocorrect;
static struct cmdnames aliases;
#define AUTOCORRECT_NEVER (-2)
#define AUTOCORRECT_IMMEDIATELY (-1)
static int git_unknown_cmd_config(const char *var, const char *value, void *cb)
{
const char *p;
if (!strcmp(var, "help.autocorrect"))
autocorrect = git_config_int(var,value);
if (!strcmp(var, "help.autocorrect")) {
if (!value)
return config_error_nonbool(var);
if (!strcmp(value, "never")) {
autocorrect = AUTOCORRECT_NEVER;
} else if (!strcmp(value, "immediate")) {
autocorrect = AUTOCORRECT_IMMEDIATELY;
} else {
int v = git_config_int(var, value);
autocorrect = (v < 0)
? AUTOCORRECT_IMMEDIATELY : v;
}
}
/* Also use aliases for command lookup */
if (skip_prefix(var, "alias.", &p))
add_cmdname(&aliases, p, strlen(p));
@ -525,6 +539,11 @@ const char *help_unknown_cmd(const char *cmd)
read_early_config(git_unknown_cmd_config, NULL);
if (autocorrect == AUTOCORRECT_NEVER) {
fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
exit(1);
}
load_command_list("git-", &main_cmds, &other_cmds);
add_cmd_list(&main_cmds, &aliases);
@ -594,7 +613,7 @@ const char *help_unknown_cmd(const char *cmd)
_("WARNING: You called a Git command named '%s', "
"which does not exist."),
cmd);
if (autocorrect < 0)
if (autocorrect == AUTOCORRECT_IMMEDIATELY)
fprintf_ln(stderr,
_("Continuing under the assumption that "
"you meant '%s'."),

View File

@ -37,16 +37,30 @@ test_expect_success 'autocorrect showing candidates' '
grep "^ distimdistim" actual
'
test_expect_success 'autocorrect running commands' '
git config help.autocorrect -1 &&
for immediate in -1 immediate
do
test_expect_success 'autocorrect running commands' '
git config help.autocorrect $immediate &&
git lfg >actual &&
echo "a single log entry" >expect &&
test_cmp expect actual &&
git lfg >actual &&
echo "a single log entry" >expect &&
test_cmp expect actual &&
git distimdist >actual &&
echo "distimdistim was called" >expect &&
test_cmp expect actual
git distimdist >actual &&
echo "distimdistim was called" >expect &&
test_cmp expect actual
'
done
test_expect_success 'autocorrect can be declined altogether' '
git config help.autocorrect never &&
test_must_fail git lfg 2>actual &&
if test_have_prereq C_LOCALE_OUTPUT
then
grep "is not a git command" actual &&
test_line_count = 1 actual
fi
'
test_done