Subject: [PATCH] help: make help.autocorrect = 1 the same as "prompt"

From: David Aguilar <[email-masked]>
Date: Sun, 19 Jan 2025 23:54:52 -0800

Choose the least surprising behavior by prompting the user
when when help.autocorrect is set to a boolean "true" value.

Make "0" and other "false" boolean values the same as "never".

Make "help.autocorrect = show" the same as the default behavior
so that users can override it in a repository-local .git/config.

Signed-off-by: David Aguilar <[email-masked]>
---
Here's what the proposed changes to make "true" = "prompt"
might look like.

 Documentation/config/help.txt | 26 ++++++++++++++++--------
 help.c                        | 14 +++++++++----
 t/t9003-help-autocorrect.sh   | 38 +++++++++++++++++------------------
 3 files changed, 47 insertions(+), 31 deletions(-)

diff --git a/Documentation/config/help.txt b/Documentation/config/help.txt
index a4c6079af8..344b4b13f7 100644
--- a/Documentation/config/help.txt
+++ b/Documentation/config/help.txt
@@ -11,14 +11,24 @@ help.autoCorrect::
 	If git detects typos and can identify exactly one valid command similar
 	to the error, git will try to suggest the correct command or even
 	run the suggestion automatically. Possible config values are:
-	 - 0: show the suggested command (default).
-	 - 1, "true", "on", "yes", "immediate": run the suggested command
-immediately.
-	 - positive number > 1: run the suggested command after specified
-deciseconds (0.1 sec).
-	 - "false", "off", "no", "never": don't run or show any suggested command.
-	 - "prompt": show the suggestion and prompt for confirmation to run
-the command.
++
+--
+show;;
+	Show the suggested command but do not run it. This is the default.
+
+immediate;;
+	Run the suggested command immediately.
+
+never, false, off, no, 0;;
+	Do not run or show the suggested command.
+
+prompt, true, on, yes, 1;;
+	Show the suggestion and prompt for confirmation to run the command.
+
+positive number greater than 1;;
+	Run the suggested command after specified deciseconds (0.1 sec).
+--
++
 
 help.htmlPath::
 	Specify the path where the HTML documentation resides. File system paths
diff --git a/help.c b/help.c
index 7148963e46..447e0c9423 100644
--- a/help.c
+++ b/help.c
@@ -552,6 +552,7 @@ struct help_unknown_cmd_config {
 	struct cmdnames aliases;
 };
 
+#define AUTOCORRECT_SHOW (-4)
 #define AUTOCORRECT_PROMPT (-3)
 #define AUTOCORRECT_NEVER (-2)
 #define AUTOCORRECT_IMMEDIATELY (-1)
@@ -560,7 +561,7 @@ static int parse_autocorrect(const char *value)
 {
 	switch (git_parse_maybe_bool_text(value)) {
 		case 1:
-			return AUTOCORRECT_IMMEDIATELY;
+			return AUTOCORRECT_PROMPT;
 		case 0:
 			return AUTOCORRECT_NEVER;
 		default: /* other random text */
@@ -573,6 +574,8 @@ static int parse_autocorrect(const char *value)
 		return AUTOCORRECT_NEVER;
 	if (!strcmp(value, "immediate"))
 		return AUTOCORRECT_IMMEDIATELY;
+	if (!strcmp(value, "show"))
+		return AUTOCORRECT_SHOW;
 
 	return 0;
 }
@@ -589,8 +592,10 @@ static int git_unknown_cmd_config(const char *var, const char *value,
 
 		if (!v) {
 			v = git_config_int(var, value, ctx->kvi);
-			if (v < 0 || v == 1)
-				v = AUTOCORRECT_IMMEDIATELY;
+			if (v == 1)
+				v = AUTOCORRECT_PROMPT;
+			else if (v <= 0)
+				v = AUTOCORRECT_NEVER;
 		}
 
 		cfg->autocorrect = v;
@@ -713,7 +718,8 @@ char *help_unknown_cmd(const char *cmd)
 		     n++)
 			; /* still counting */
 	}
-	if (cfg.autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
+	if (cfg.autocorrect && cfg.autocorrect != AUTOCORRECT_SHOW &&
+	    n == 1 && SIMILAR_ENOUGH(best_similarity)) {
 		char *assumed = xstrdup(main_cmds.names[0]->name);
 
 		fprintf_ln(stderr,
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 85a5074b5e..ea20526248 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -29,7 +29,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'autocorrect showing candidates' '
-	git config help.autocorrect 0 &&
+	git config help.autocorrect show &&
 
 	test_must_fail git lfg 2>actual &&
 	grep "^	lgf" actual &&
@@ -38,28 +38,28 @@ test_expect_success 'autocorrect showing candidates' '
 	grep "^	distimdistim" actual
 '
 
-for immediate in -1 immediate
-do
-	test_expect_success 'autocorrect running commands' '
-		git config help.autocorrect $immediate &&
+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
-	'
-done
+	git distimdist >actual &&
+	echo "distimdistim was called" >expect &&
+	test_cmp expect actual
+'
 
-test_expect_success 'autocorrect can be declined altogether' '
-	git config help.autocorrect never &&
+for never in -1 0 no false never
+do
+	test_expect_success 'autocorrect can be declined altogether' '
+		git config help.autocorrect $never &&
 
-	test_must_fail git lfg 2>actual &&
-	grep "is not a git command" actual &&
-	test_line_count = 1 actual
-'
+		test_must_fail git lfg 2>actual &&
+		grep "is not a git command" actual &&
+		test_line_count = 1 actual
+	'
+done
 
 test_expect_success 'autocorrect works in work tree created from bare repo' '
 	git clone --bare . bare.git &&
-- 
2.48.0.rc2.33.gfa4adeb460