All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] help: prompt user to run corrected command on typo
@ 2026-06-18 14:26 calicomills
  2026-06-18 17:48 ` Justin Tobler
  0 siblings, 1 reply; 8+ messages in thread
From: calicomills @ 2026-06-18 14:26 UTC (permalink / raw)
  To: git; +Cc: gitster

From 0dc9e5c4593611b75e7003e8fdbea9370524c05b Mon Sep 17 00:00:00 2001
From: calicomills <jishnuck26@gmail.com>
Date: Thu, 18 Jun 2026 19:47:12 +0530
Subject: [PATCH] help: prompt user to run corrected command on typo

When a user mistypes a git command and there is exactly one similar
command, git currently prints a suggestion but exits, requiring the
user to retype the corrected command manually.

Instead, when stdin and stderr are both connected to a terminal and
there is a single best match, prompt the user with:

  Did you mean 'git checkout neo'? [y/N]

The full corrected invocation (command + original arguments) is shown
in the prompt so the user knows exactly what will run. Answering 'y'
re-executes git with the corrected command and all original arguments.
Answering anything else exits as before.

When there are multiple similarly-named commands, or when running
non-interactively (scripts, pipes), the original behaviour of printing
the suggestion list and exiting is preserved.

The help_unknown_cmd() signature is updated to accept the full args
vector so the prompt can include the original arguments alongside the
corrected command name.

Add tests to t9003 covering:
- non-interactive single match: falls back to suggestion list
- non-interactive multiple matches: falls back to suggestion list
- interactive single match, 'y': corrected command runs (TTY prereq)
- interactive single match, 'n': exits cleanly (TTY prereq)

Signed-off-by: calicomills <jishnuck26@gmail.com>
---
 builtin/help.c              |  2 +-
 git.c                       |  2 +-
 help.c                      | 40 ++++++++++++++++++++++------
 help.h                      |  3 ++-
 t/t9003-help-autocorrect.sh | 53 +++++++++++++++++++++++++++++++++++++
 5 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/builtin/help.c b/builtin/help.c
index a140339999..b17e61ccc8 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -618,7 +618,7 @@ static char *check_git_cmd(const char *cmd)
 	}
 
 	if (exclude_guides)
-		return help_unknown_cmd(cmd);
+		return help_unknown_cmd(cmd, NULL);
 
 	return xstrdup(cmd);
 }
diff --git a/git.c b/git.c
index 36f08891ef..d379cc85bb 100644
--- a/git.c
+++ b/git.c
@@ -994,7 +994,7 @@ int cmd_main(int argc, const char **argv)
 			exit(1);
 		}
 		if (!done_help) {
-			char *assumed = help_unknown_cmd(cmd);
+			char *assumed = help_unknown_cmd(cmd, &args);
 			strvec_replace(&args, 0, assumed);
 			free(assumed);
 			cmd = args.v[0];
diff --git a/help.c b/help.c
index 46241492ce..30f32a7206 100644
--- a/help.c
+++ b/help.c
@@ -641,7 +641,7 @@ static const char bad_interpreter_advice[] =
 	N_("'%s' appears to be a git command, but we were not\n"
 	"able to execute it. Maybe git-%s is broken?");
 
-char *help_unknown_cmd(const char *cmd)
+char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 {
 	struct help_unknown_cmd_config cfg = { 0 };
 	int i, n, best_similarity = 0;
@@ -762,13 +762,37 @@ char *help_unknown_cmd(const char *cmd)
 	fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
 
 	if (SIMILAR_ENOUGH(best_similarity)) {
-		fprintf_ln(stderr,
-			   Q_("\nThe most similar command is",
-			      "\nThe most similar commands are",
-			   n));
-
-		for (i = 0; i < n; i++)
-			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		if (n == 1 && isatty(0) && isatty(2)) {
+			char *answer;
+			struct strbuf msg = STRBUF_INIT;
+			struct strbuf full_cmd = STRBUF_INIT;
+			strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
+			if (args) {
+				for (size_t j = 1; j < args->nr; j++) {
+					strbuf_addch(&full_cmd, ' ');
+					strbuf_addstr(&full_cmd, args->v[j]);
+				}
+			}
+			strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
+				    full_cmd.buf);
+			strbuf_release(&full_cmd);
+			answer = git_prompt(msg.buf, PROMPT_ECHO);
+			strbuf_release(&msg);
+			if (starts_with(answer, "y") || starts_with(answer, "Y")) {
+				char *assumed = xstrdup(main_cmds.names[0]->name);
+				cmdnames_release(&cfg.aliases);
+				cmdnames_release(&main_cmds);
+				cmdnames_release(&other_cmds);
+				return assumed;
+			}
+		} else {
+			fprintf_ln(stderr,
+				   Q_("\nThe most similar command is",
+				      "\nThe most similar commands are",
+				   n));
+			for (i = 0; i < n; i++)
+				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		}
 	}
 
 	exit(1);
diff --git a/help.h b/help.h
index c54bf0977d..a8c465b3df 100644
--- a/help.h
+++ b/help.h
@@ -32,7 +32,8 @@ void list_all_other_cmds(struct string_list *list);
 void list_cmds_by_category(struct string_list *list,
 			   const char *category);
 void list_cmds_by_config(struct string_list *list);
-char *help_unknown_cmd(const char *cmd);
+#include "strvec.h"
+char *help_unknown_cmd(const char *cmd, const struct strvec *args);
 void load_command_list(const char *prefix,
 		       struct cmdnames *main_cmds,
 		       struct cmdnames *other_cmds);
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 8da318d2b5..6fe2da1595 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -70,4 +70,57 @@ test_expect_success 'autocorrect works in work tree created from bare repo' '
 	git -C worktree -c help.autocorrect=immediate status
 '
 
+# Default behaviour (no help.autocorrect set): when there is exactly one
+# similar command but the session is non-interactive, fall back to printing
+# the suggestion list and exiting rather than showing a prompt.
+test_expect_success 'default: single match non-interactive shows suggestion and fails' '
+	test_might_fail git config --unset help.autocorrect &&
+
+	test_must_fail git lfg 2>actual &&
+	grep "most similar command" actual &&
+	grep "lgf" actual
+'
+
+test_expect_success 'default: multiple matches non-interactive shows list and fails' '
+	test_might_fail git config --unset help.autocorrect &&
+
+	test_must_fail git com 2>actual &&
+	grep "most similar commands" actual &&
+	grep "commit" actual
+'
+
+# Interactive prompt tests require a real TTY.  On macOS the TTY prereq is
+# skipped due to IO::Pty reliability issues; these tests run on Linux CI.
+test_expect_success TTY 'default: single match interactive, answer y runs command' '
+	git config --unset help.autocorrect &&
+
+	write_script git-typotest <<-\EOF &&
+		echo typotest-ran
+	EOF
+	PATH="$PATH:." export PATH &&
+
+	# Feed "y" to /dev/tty via a wrapper that answers the prompt
+	write_script answer-prompt <<-\EOF &&
+		# Write the answer to the controlling terminal
+		printf "y\n" >/dev/tty
+		exec "$@"
+	EOF
+
+	test_terminal ./answer-prompt git typotest 2>err >out &&
+	grep "typotest-ran" out &&
+	grep "Did you mean" err
+'
+
+test_expect_success TTY 'default: single match interactive, answer n exits cleanly' '
+	git config --unset help.autocorrect &&
+
+	write_script answer-prompt-no <<-\EOF &&
+		printf "n\n" >/dev/tty
+		exec "$@"
+	EOF
+
+	test_must_fail test_terminal ./answer-prompt-no git typotest 2>err &&
+	grep "Did you mean" err
+'
+
 test_done
-- 
2.50.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] help: prompt user to run corrected command on typo
  2026-06-18 14:26 [PATCH] help: prompt user to run corrected command on typo calicomills
@ 2026-06-18 17:48 ` Justin Tobler
  2026-06-19  6:05   ` Jishnu C K
  2026-06-19 17:04   ` [PATCH v2] help: include arguments in autocorrect=prompt message Jishnu C K
  0 siblings, 2 replies; 8+ messages in thread
From: Justin Tobler @ 2026-06-18 17:48 UTC (permalink / raw)
  To: calicomills; +Cc: git, gitster

On 26/06/18 07:26AM, calicomills wrote:
> From 0dc9e5c4593611b75e7003e8fdbea9370524c05b Mon Sep 17 00:00:00 2001
> From: calicomills <jishnuck26@gmail.com>
> Date: Thu, 18 Jun 2026 19:47:12 +0530
> Subject: [PATCH] help: prompt user to run corrected command on typo
> 
> When a user mistypes a git command and there is exactly one similar
> command, git currently prints a suggestion but exits, requiring the
> user to retype the corrected command manually.
> 
> Instead, when stdin and stderr are both connected to a terminal and
> there is a single best match, prompt the user with:
> 
>   Did you mean 'git checkout neo'? [y/N]
> 
> The full corrected invocation (command + original arguments) is shown
> in the prompt so the user knows exactly what will run. Answering 'y'
> re-executes git with the corrected command and all original arguments.
> Answering anything else exits as before.

Isn't this already possible via setting `help.autoCorrect=prompt` in the
config? For example:

  git -c help.autoCorrect=prompt comit --allow-empty -m init

seems to already do exactly what is proposed here.

-Justin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] help: prompt user to run corrected command on typo
  2026-06-18 17:48 ` Justin Tobler
@ 2026-06-19  6:05   ` Jishnu C K
  2026-06-19 16:24     ` Justin Tobler
  2026-06-19 16:37     ` Junio C Hamano
  2026-06-19 17:04   ` [PATCH v2] help: include arguments in autocorrect=prompt message Jishnu C K
  1 sibling, 2 replies; 8+ messages in thread
From: Jishnu C K @ 2026-06-19  6:05 UTC (permalink / raw)
  To: Justin Tobler; +Cc: git, gitster

On Thu, Jun 18, 2026, Justin Tobler wrote:
> Isn't this already possible via setting `help.autoCorrect=prompt` in the
> config?

Thank you for the review.

You're right that `help.autocorrect=prompt` exists and is similar.
Our change differs in two ways:

1. No configuration needed. The existing prompt mode requires the user
   to explicitly set `help.autocorrect=prompt`. Most users are unaware
   of this option, so they see a suggestion and must retype the full
   command manually. Our change makes the interactive prompt the
   default behaviour when stdin and stderr are a terminal.

2. The prompt includes the original arguments. `help.autocorrect=prompt`
   shows only:

     Run 'checkout' instead [y/N]?

   Our prompt shows the full corrected invocation:

     Did you mean 'git checkout neo'? [y/N]

   This lets the user confirm exactly what will run, including their
   original arguments, before pressing 'y'.

If the consensus is that the default should remain non-interactive,
we are happy to rework this as an improvement to the existing
`autocorrect=prompt` mode (showing args in the prompt) with
documentation updates to make the option more discoverable.

-- 
Jishnu C K

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] help: prompt user to run corrected command on typo
  2026-06-19  6:05   ` Jishnu C K
@ 2026-06-19 16:24     ` Justin Tobler
  2026-06-19 16:37     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: Justin Tobler @ 2026-06-19 16:24 UTC (permalink / raw)
  To: Jishnu C K; +Cc: git, gitster

On 26/06/18 11:05PM, Jishnu C K wrote:
> If the consensus is that the default should remain non-interactive,
> we are happy to rework this as an improvement to the existing
> `autocorrect=prompt` mode (showing args in the prompt) with
> documentation updates to make the option more discoverable.

I'm not sure what the current consensus is here, but as it would be a
change to the existing behavior it would need its merits discussed
accordingly. Personally, I think requiring users to opt-in to
autocorrect isn't a significant barrier itself. It does require that
users know that the option is available in the first place though. So if
discoverablility of this feature is lacking and can be improved in
documentation, that certainly seems like a reasonable change. 

Regarding changing the prompt to display command arguments, I'm
relatively indifferent towards it. I'm not sure it adds a ton of value,
but maybe other folks will have a different opinion.

-Justin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] help: prompt user to run corrected command on typo
  2026-06-19  6:05   ` Jishnu C K
  2026-06-19 16:24     ` Justin Tobler
@ 2026-06-19 16:37     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2026-06-19 16:37 UTC (permalink / raw)
  To: Jishnu C K; +Cc: Justin Tobler, git

Jishnu C K <jishnuck26@gmail.com> writes:

> You're right that `help.autocorrect=prompt` exists and is similar.
> Our change differs in two ways:
>
> 1. No configuration needed. The existing prompt mode requires the user

I do not particularly see it as an advantage.

> 2. The prompt includes the original arguments. `help.autocorrect=prompt`
>    shows only:
>
>      Run 'checkout' instead [y/N]?
>
>    Our prompt shows the full corrected invocation:
>
>      Did you mean 'git checkout neo'? [y/N]
>
>    This lets the user confirm exactly what will run, including their
>    original arguments, before pressing 'y'.

This may be an improvement, but is there a reason why such a change
must be done as a parallel and unrelated (re)implementation and not
as an incrementa improvement to the code that implements the
existing feature?




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] help: include arguments in autocorrect=prompt message
  2026-06-18 17:48 ` Justin Tobler
  2026-06-19  6:05   ` Jishnu C K
@ 2026-06-19 17:04   ` Jishnu C K
  2026-06-23 15:21     ` Jishnu C K
  2026-06-23 16:09     ` Junio C Hamano
  1 sibling, 2 replies; 8+ messages in thread
From: Jishnu C K @ 2026-06-19 17:04 UTC (permalink / raw)
  To: git; +Cc: gitster, Justin Tobler

v2: Reworked as an incremental improvement to the existing
autocorrect=prompt code path rather than a parallel reimplementation,
per feedback from Junio and Justin.

---
From a4e8fb6fd6dd6a501e565c7500cbf927d7cb0b42 Mon Sep 17 00:00:00 2001
From: calicomills <jishnuck26@gmail.com>
Date: Fri, 19 Jun 2026 13:01:40 +0530
Subject: [PATCH v2 v2] help: include arguments in autocorrect=prompt message

When 'help.autocorrect=prompt' is configured and the user mistypes
a git command, the prompt currently shows only the corrected command
name:

  Run 'checkout' instead [y/N]?

This leaves the user unsure whether their original arguments will be
preserved. Update the prompt to include the full corrected invocation:

  Run 'git checkout neo' instead [y/N]?

The help_unknown_cmd() signature is updated to accept the args vector
so the prompt can show the original arguments alongside the corrected
command name. Callers that do not have access to the args (e.g.
builtin/help.c) pass NULL, which is handled gracefully.

Signed-off-by: calicomills <jishnuck26@gmail.com>
---
 help.c                      | 49 +++++++++++++----------------------
 t/t9003-help-autocorrect.sh | 51 +++++--------------------------------
 2 files changed, 23 insertions(+), 77 deletions(-)

diff --git a/help.c b/help.c
index 30f32a7206..9ea4c076e1 100644
--- a/help.c
+++ b/help.c
@@ -739,7 +739,16 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 		else if (cfg.autocorrect == AUTOCORRECT_PROMPT) {
 			char *answer;
 			struct strbuf msg = STRBUF_INIT;
-			strbuf_addf(&msg, _("Run '%s' instead [y/N]? "), assumed);
+			struct strbuf full_cmd = STRBUF_INIT;
+			strbuf_addstr(&full_cmd, assumed);
+			if (args) {
+				for (size_t j = 1; j < args->nr; j++) {
+					strbuf_addch(&full_cmd, ' ');
+					strbuf_addstr(&full_cmd, args->v[j]);
+				}
+			}
+			strbuf_addf(&msg, _("Run 'git %s' instead [y/N]? "), full_cmd.buf);
+			strbuf_release(&full_cmd);
 			answer = git_prompt(msg.buf, PROMPT_ECHO);
 			strbuf_release(&msg);
 			if (!(starts_with(answer, "y") ||
@@ -762,37 +771,13 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 	fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
 
 	if (SIMILAR_ENOUGH(best_similarity)) {
-		if (n == 1 && isatty(0) && isatty(2)) {
-			char *answer;
-			struct strbuf msg = STRBUF_INIT;
-			struct strbuf full_cmd = STRBUF_INIT;
-			strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
-			if (args) {
-				for (size_t j = 1; j < args->nr; j++) {
-					strbuf_addch(&full_cmd, ' ');
-					strbuf_addstr(&full_cmd, args->v[j]);
-				}
-			}
-			strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
-				    full_cmd.buf);
-			strbuf_release(&full_cmd);
-			answer = git_prompt(msg.buf, PROMPT_ECHO);
-			strbuf_release(&msg);
-			if (starts_with(answer, "y") || starts_with(answer, "Y")) {
-				char *assumed = xstrdup(main_cmds.names[0]->name);
-				cmdnames_release(&cfg.aliases);
-				cmdnames_release(&main_cmds);
-				cmdnames_release(&other_cmds);
-				return assumed;
-			}
-		} else {
-			fprintf_ln(stderr,
-				   Q_("\nThe most similar command is",
-				      "\nThe most similar commands are",
-				   n));
-			for (i = 0; i < n; i++)
-				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
-		}
+		fprintf_ln(stderr,
+			   Q_("\nThe most similar command is",
+			      "\nThe most similar commands are",
+			   n));
+
+		for (i = 0; i < n; i++)
+			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
 	}
 
 	exit(1);
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 6fe2da1595..75821d63e1 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -70,57 +70,18 @@ test_expect_success 'autocorrect works in work tree created from bare repo' '
 	git -C worktree -c help.autocorrect=immediate status
 '
 
-# Default behaviour (no help.autocorrect set): when there is exactly one
-# similar command but the session is non-interactive, fall back to printing
-# the suggestion list and exiting rather than showing a prompt.
-test_expect_success 'default: single match non-interactive shows suggestion and fails' '
-	test_might_fail git config --unset help.autocorrect &&
-
-	test_must_fail git lfg 2>actual &&
-	grep "most similar command" actual &&
-	grep "lgf" actual
-'
-
-test_expect_success 'default: multiple matches non-interactive shows list and fails' '
-	test_might_fail git config --unset help.autocorrect &&
-
-	test_must_fail git com 2>actual &&
-	grep "most similar commands" actual &&
-	grep "commit" actual
-'
-
-# Interactive prompt tests require a real TTY.  On macOS the TTY prereq is
-# skipped due to IO::Pty reliability issues; these tests run on Linux CI.
-test_expect_success TTY 'default: single match interactive, answer y runs command' '
-	git config --unset help.autocorrect &&
-
-	write_script git-typotest <<-\EOF &&
-		echo typotest-ran
-	EOF
-	PATH="$PATH:." export PATH &&
-
-	# Feed "y" to /dev/tty via a wrapper that answers the prompt
-	write_script answer-prompt <<-\EOF &&
-		# Write the answer to the controlling terminal
-		printf "y\n" >/dev/tty
-		exec "$@"
-	EOF
-
-	test_terminal ./answer-prompt git typotest 2>err >out &&
-	grep "typotest-ran" out &&
-	grep "Did you mean" err
-'
-
-test_expect_success TTY 'default: single match interactive, answer n exits cleanly' '
-	git config --unset help.autocorrect &&
+# autocorrect=prompt should include the original arguments in the prompt.
+# Requires a TTY; skipped on macOS due to IO::Pty reliability issues.
+test_expect_success TTY 'autocorrect=prompt includes arguments in prompt' '
+	git config help.autocorrect prompt &&
 
 	write_script answer-prompt-no <<-\EOF &&
 		printf "n\n" >/dev/tty
 		exec "$@"
 	EOF
 
-	test_must_fail test_terminal ./answer-prompt-no git typotest 2>err &&
-	grep "Did you mean" err
+	test_must_fail test_terminal ./answer-prompt-no git lfg --oneline 2>actual &&
+	grep "lgf --oneline" actual
 '
 
 test_done
-- 
2.50.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] help: include arguments in autocorrect=prompt message
  2026-06-19 17:04   ` [PATCH v2] help: include arguments in autocorrect=prompt message Jishnu C K
@ 2026-06-23 15:21     ` Jishnu C K
  2026-06-23 16:09     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: Jishnu C K @ 2026-06-23 15:21 UTC (permalink / raw)
  To: git; +Cc: gitster, Justin Tobler

Any review comments?
Sent from my iPhone

> On 19 Jun 2026, at 10:34 PM, Jishnu C K <jishnuck26@gmail.com> wrote:
> 
> v2: Reworked as an incremental improvement to the existing
> autocorrect=prompt code path rather than a parallel reimplementation,
> per feedback from Junio and Justin.
> 
> ---
> From a4e8fb6fd6dd6a501e565c7500cbf927d7cb0b42 Mon Sep 17 00:00:00 2001
> From: calicomills <jishnuck26@gmail.com>
> Date: Fri, 19 Jun 2026 13:01:40 +0530
> Subject: [PATCH v2 v2] help: include arguments in autocorrect=prompt message
> 
> When 'help.autocorrect=prompt' is configured and the user mistypes
> a git command, the prompt currently shows only the corrected command
> name:
> 
>  Run 'checkout' instead [y/N]?
> 
> This leaves the user unsure whether their original arguments will be
> preserved. Update the prompt to include the full corrected invocation:
> 
>  Run 'git checkout neo' instead [y/N]?
> 
> The help_unknown_cmd() signature is updated to accept the args vector
> so the prompt can show the original arguments alongside the corrected
> command name. Callers that do not have access to the args (e.g.
> builtin/help.c) pass NULL, which is handled gracefully.
> 
> Signed-off-by: calicomills <jishnuck26@gmail.com>
> ---
> help.c                      | 49 +++++++++++++----------------------
> t/t9003-help-autocorrect.sh | 51 +++++--------------------------------
> 2 files changed, 23 insertions(+), 77 deletions(-)
> 
> diff --git a/help.c b/help.c
> index 30f32a7206..9ea4c076e1 100644
> --- a/help.c
> +++ b/help.c
> @@ -739,7 +739,16 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
>        else if (cfg.autocorrect == AUTOCORRECT_PROMPT) {
>            char *answer;
>            struct strbuf msg = STRBUF_INIT;
> -            strbuf_addf(&msg, _("Run '%s' instead [y/N]? "), assumed);
> +            struct strbuf full_cmd = STRBUF_INIT;
> +            strbuf_addstr(&full_cmd, assumed);
> +            if (args) {
> +                for (size_t j = 1; j < args->nr; j++) {
> +                    strbuf_addch(&full_cmd, ' ');
> +                    strbuf_addstr(&full_cmd, args->v[j]);
> +                }
> +            }
> +            strbuf_addf(&msg, _("Run 'git %s' instead [y/N]? "), full_cmd.buf);
> +            strbuf_release(&full_cmd);
>            answer = git_prompt(msg.buf, PROMPT_ECHO);
>            strbuf_release(&msg);
>            if (!(starts_with(answer, "y") ||
> @@ -762,37 +771,13 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
>    fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
> 
>    if (SIMILAR_ENOUGH(best_similarity)) {
> -        if (n == 1 && isatty(0) && isatty(2)) {
> -            char *answer;
> -            struct strbuf msg = STRBUF_INIT;
> -            struct strbuf full_cmd = STRBUF_INIT;
> -            strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
> -            if (args) {
> -                for (size_t j = 1; j < args->nr; j++) {
> -                    strbuf_addch(&full_cmd, ' ');
> -                    strbuf_addstr(&full_cmd, args->v[j]);
> -                }
> -            }
> -            strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
> -                    full_cmd.buf);
> -            strbuf_release(&full_cmd);
> -            answer = git_prompt(msg.buf, PROMPT_ECHO);
> -            strbuf_release(&msg);
> -            if (starts_with(answer, "y") || starts_with(answer, "Y")) {
> -                char *assumed = xstrdup(main_cmds.names[0]->name);
> -                cmdnames_release(&cfg.aliases);
> -                cmdnames_release(&main_cmds);
> -                cmdnames_release(&other_cmds);
> -                return assumed;
> -            }
> -        } else {
> -            fprintf_ln(stderr,
> -                   Q_("\nThe most similar command is",
> -                      "\nThe most similar commands are",
> -                   n));
> -            for (i = 0; i < n; i++)
> -                fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
> -        }
> +        fprintf_ln(stderr,
> +               Q_("\nThe most similar command is",
> +                  "\nThe most similar commands are",
> +               n));
> +
> +        for (i = 0; i < n; i++)
> +            fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
>    }
> 
>    exit(1);
> diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
> index 6fe2da1595..75821d63e1 100755
> --- a/t/t9003-help-autocorrect.sh
> +++ b/t/t9003-help-autocorrect.sh
> @@ -70,57 +70,18 @@ test_expect_success 'autocorrect works in work tree created from bare repo' '
>    git -C worktree -c help.autocorrect=immediate status
> '
> 
> -# Default behaviour (no help.autocorrect set): when there is exactly one
> -# similar command but the session is non-interactive, fall back to printing
> -# the suggestion list and exiting rather than showing a prompt.
> -test_expect_success 'default: single match non-interactive shows suggestion and fails' '
> -    test_might_fail git config --unset help.autocorrect &&
> -
> -    test_must_fail git lfg 2>actual &&
> -    grep "most similar command" actual &&
> -    grep "lgf" actual
> -'
> -
> -test_expect_success 'default: multiple matches non-interactive shows list and fails' '
> -    test_might_fail git config --unset help.autocorrect &&
> -
> -    test_must_fail git com 2>actual &&
> -    grep "most similar commands" actual &&
> -    grep "commit" actual
> -'
> -
> -# Interactive prompt tests require a real TTY.  On macOS the TTY prereq is
> -# skipped due to IO::Pty reliability issues; these tests run on Linux CI.
> -test_expect_success TTY 'default: single match interactive, answer y runs command' '
> -    git config --unset help.autocorrect &&
> -
> -    write_script git-typotest <<-\EOF &&
> -        echo typotest-ran
> -    EOF
> -    PATH="$PATH:." export PATH &&
> -
> -    # Feed "y" to /dev/tty via a wrapper that answers the prompt
> -    write_script answer-prompt <<-\EOF &&
> -        # Write the answer to the controlling terminal
> -        printf "y\n" >/dev/tty
> -        exec "$@"
> -    EOF
> -
> -    test_terminal ./answer-prompt git typotest 2>err >out &&
> -    grep "typotest-ran" out &&
> -    grep "Did you mean" err
> -'
> -
> -test_expect_success TTY 'default: single match interactive, answer n exits cleanly' '
> -    git config --unset help.autocorrect &&
> +# autocorrect=prompt should include the original arguments in the prompt.
> +# Requires a TTY; skipped on macOS due to IO::Pty reliability issues.
> +test_expect_success TTY 'autocorrect=prompt includes arguments in prompt' '
> +    git config help.autocorrect prompt &&
> 
>    write_script answer-prompt-no <<-\EOF &&
>        printf "n\n" >/dev/tty
>        exec "$@"
>    EOF
> 
> -    test_must_fail test_terminal ./answer-prompt-no git typotest 2>err &&
> -    grep "Did you mean" err
> +    test_must_fail test_terminal ./answer-prompt-no git lfg --oneline 2>actual &&
> +    grep "lgf --oneline" actual
> '
> 
> test_done
> --
> 2.50.1
> 
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] help: include arguments in autocorrect=prompt message
  2026-06-19 17:04   ` [PATCH v2] help: include arguments in autocorrect=prompt message Jishnu C K
  2026-06-23 15:21     ` Jishnu C K
@ 2026-06-23 16:09     ` Junio C Hamano
  1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2026-06-23 16:09 UTC (permalink / raw)
  To: Jishnu C K; +Cc: git, Justin Tobler

Jishnu C K <jishnuck26@gmail.com> writes:

> v2: Reworked as an incremental improvement to the existing
> autocorrect=prompt code path rather than a parallel reimplementation,
> per feedback from Junio and Justin.
>
> ---
> From a4e8fb6fd6dd6a501e565c7500cbf927d7cb0b42 Mon Sep 17 00:00:00 2001
> From: calicomills <jishnuck26@gmail.com>
> Date: Fri, 19 Jun 2026 13:01:40 +0530
> Subject: [PATCH v2 v2] help: include arguments in autocorrect=prompt message

To learn what a typical v2 of a single-patch topic should look like,
see

  https://lore.kernel.org/git/aipTOsH8LKTSwglj@collabora.com/

for an example.

 - Having auxiliary comments explaining why there is this v2,
   including description of the difference since v1, is good, but
   have it below the three-dash line after your sign off, not at the
   beginning.

 - Please do not include "From a4e8fb6f..." line, which is meant as
   a separator in multi-patch output from the git format-patch
   command; knowing the exact commit object name you took the patch
   from in your repository would not help anybody.

 - Do not include "From:" in the body of the message either, unless
   you are relaying somebody else's patch, i.e., when the From
   e-mail header (you) does not name the person who wrote the patch
   (somebody else).

 - Do not include "Date:" in the body of the message either, as that
   is the timestamp you wrote the change, but we care more about the
   time when the general public first saw the patch, which is in the
   e-mail header already.

 - Do not include "Subject:" in the body of the message either, as
   that should be on the Subject e-mail header.

> When 'help.autocorrect=prompt' is configured and the user mistypes
> a git command, the prompt currently shows only the corrected command
> name:
>
>   Run 'checkout' instead [y/N]?
>
> This leaves the user unsure whether their original arguments will be
> preserved. Update the prompt to include the full corrected invocation:
>
>   Run 'git checkout neo' instead [y/N]?
>
> The help_unknown_cmd() signature is updated to accept the args vector
> so the prompt can show the original arguments alongside the corrected
> command name. Callers that do not have access to the args (e.g.
> builtin/help.c) pass NULL, which is handled gracefully.
>
> Signed-off-by: calicomills <jishnuck26@gmail.com>

Documentation/SubmittingPatches[[real-name]] prefers to see us
interacting with humans with real-sounding names, not handles.

> ---
>  help.c                      | 49 +++++++++++++----------------------
>  t/t9003-help-autocorrect.sh | 51 +++++--------------------------------
>  2 files changed, 23 insertions(+), 77 deletions(-)
>
> diff --git a/help.c b/help.c
> index 30f32a7206..9ea4c076e1 100644
> --- a/help.c
> +++ b/help.c
> @@ -739,7 +739,16 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
>  		else if (cfg.autocorrect == AUTOCORRECT_PROMPT) {
>  			char *answer;
>  			struct strbuf msg = STRBUF_INIT;
> -			strbuf_addf(&msg, _("Run '%s' instead [y/N]? "), assumed);
> +			struct strbuf full_cmd = STRBUF_INIT;
> +			strbuf_addstr(&full_cmd, assumed);
> +			if (args) {
> +				for (size_t j = 1; j < args->nr; j++) {
> +					strbuf_addch(&full_cmd, ' ');
> +					strbuf_addstr(&full_cmd, args->v[j]);
> +				}
> +			}
> +			strbuf_addf(&msg, _("Run 'git %s' instead [y/N]? "), full_cmd.buf);
> +			strbuf_release(&full_cmd);

This change seems to match what is explained in the proposed log
message.  Instead of giving the "assumed" command without its
arguments, the full command line is gprepared to be given in 'msg'.

But if we really wanted to let these be cut-and-paste, don't you
need to shell-quote the command line?  If the user typed

	$ git comit -m "Hello world"

the above makes

	Run 'git commit -m hello world' instead [y/N]?

which would record the change made only to the file "world" with log
message "hello", which is not what the user wanted to do.

> @@ -762,37 +771,13 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
>  	fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
>  
>  	if (SIMILAR_ENOUGH(best_similarity)) {
> -		if (n == 1 && isatty(0) && isatty(2)) {
> -			char *answer;
> -			struct strbuf msg = STRBUF_INIT;
> -			struct strbuf full_cmd = STRBUF_INIT;
> -			strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
> -			if (args) {
> -				for (size_t j = 1; j < args->nr; j++) {
> -					strbuf_addch(&full_cmd, ' ');
> -					strbuf_addstr(&full_cmd, args->v[j]);
> -				}
> -			}
> -			strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
> -				    full_cmd.buf);
> -			strbuf_release(&full_cmd);
> -			answer = git_prompt(msg.buf, PROMPT_ECHO);
> -			strbuf_release(&msg);
> -			if (starts_with(answer, "y") || starts_with(answer, "Y")) {
> -				char *assumed = xstrdup(main_cmds.names[0]->name);
> -				cmdnames_release(&cfg.aliases);
> -				cmdnames_release(&main_cmds);
> -				cmdnames_release(&other_cmds);
> -				return assumed;
> -			}

What is this removal about?  The original used to give interactive
prompt to let the user say "Yes", but with this part removed, it no
longer offers the "well we have only one candidate, do you want to
run that one?", and you instead ...

> -		} else {
> -			fprintf_ln(stderr,
> -				   Q_("\nThe most similar command is",
> -				      "\nThe most similar commands are",
> -				   n));
> -			for (i = 0; i < n; i++)
> -				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
> -		}

... only give "these are the possible candidates?"

> +		fprintf_ln(stderr,
> +			   Q_("\nThe most similar command is",
> +			      "\nThe most similar commands are",
> +			   n));
> +
> +		for (i = 0; i < n; i++)
> +			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
>  	}

Puzzled.

Worse, this [v2] does not even apply cleanly to any of the trees we
have.

Aha!  Is the removal I see above a mere "oops, this was wrong, so
remove it" done on top of a previous iteration of the patch?

Please do not do that.  It would mean we will keep unwanted code
that went into a wrong direction (which is v1) in our history.

The development may wander around in different directions like a
drunken man, changing course every time patches are updated, until
it finally gets right, but the name of the game around here, before
your change is merged to 'next', is to "pretend to be a more perfect
developer than you actually are" ;-).  You can pretend that you
never made a design mistake you made in [v1], and instead directly
arrived at a good state from the state of our public tree.  That
means [v2] (and any subsequent rerolls, until your seires gets
merged to 'next') must apply directly without any of the older
iterations to 'master' (or if it is a bugfix, 'maint') branch.

Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-06-23 16:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-18 14:26 [PATCH] help: prompt user to run corrected command on typo calicomills
2026-06-18 17:48 ` Justin Tobler
2026-06-19  6:05   ` Jishnu C K
2026-06-19 16:24     ` Justin Tobler
2026-06-19 16:37     ` Junio C Hamano
2026-06-19 17:04   ` [PATCH v2] help: include arguments in autocorrect=prompt message Jishnu C K
2026-06-23 15:21     ` Jishnu C K
2026-06-23 16:09     ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.