Subject: [PATCH 4/4] builtins: show help on "-h"/"--help-all" with more than 2 arguments left

From: "D. Ben Knoble" <[email-masked]>
Date: Sat, 26 Jul 2025 12:53:14 -0400

When asking for short help on a previous command, the user may use their
shell history to recall a command like

    git rebase new-base

Then inserting "-h" after "rebase" doesn't yield the help; make it so.

Signed-off-by: D. Ben Knoble <[email-masked]>
---

Notes:
    I reviewed the following results
    
        git grep '[^[:alpha:]-]-h' 'Documentation/**adoc' ':(exclude)Documentation/RelNotes'
    
    The 2 commands that accept "-h" to mean other things are git-grep(1) and
    git-ls-remote(1).
    
    - "git grep -h 123" gives results sans filenames, while a lone "-h"
      gives help. Behavior is unchanged from 2.48.1 (my local install).
    - "git ls-remote -h" gives help; "git ls-remote -h origin" lists heads.
      Behavior is unchanged from 2.48.1.
    
    But I'd welcome a more thorough check to make sure I didn't overlook
    things. This is probably the most controversial patch, and if it's
    dropped, that would be alright (though it is helpful for me to reduce
    typing).

 builtin/merge-recursive.c | 2 +-
 git.c                     | 2 +-
 parse-options.c           | 2 +-
 usage.c                   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 17aa4db37a..c433d26bdf 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -38,7 +38,7 @@ int cmd_merge_recursive(int argc,
 	if (argv[0] && ends_with(argv[0], "-subtree"))
 		o.subtree_shift = "";
 
-	if (argc == 2 && (!strcmp(argv[1], "-h") ||
+	if (argc >= 2 && (!strcmp(argv[1], "-h") ||
 			  !strcmp(argv[1], "--help-all"))) {
 		struct strbuf msg = STRBUF_INIT;
 		strbuf_addf(&msg, builtin_merge_recursive_usage, argv[0]);
diff --git a/git.c b/git.c
index 40d3df1b76..7fe4e15e2d 100644
--- a/git.c
+++ b/git.c
@@ -445,7 +445,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct
 	const char *prefix;
 	int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY));
 
-	help = argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help-all"));
+	help = argc >= 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help-all"));
 	if (help && (run_setup & RUN_SETUP))
 		/* demote to GENTLY to allow 'git cmd -h' outside repo */
 		run_setup = RUN_SETUP_GENTLY;
diff --git a/parse-options.c b/parse-options.c
index e3ed42f709..b9a31c261c 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1464,7 +1464,7 @@ void show_usage_with_options_if_asked(int ac, const char **av,
 				      const char * const *usagestr,
 				      const struct option *opts)
 {
-	if (ac == 2) {
+	if (ac >= 2) {
 		if (!strcmp(av[1], "-h")) {
 			usage_with_options_internal(NULL, usagestr, opts, style_normal, to_out);
 			exit(129);
diff --git a/usage.c b/usage.c
index 4c245ba0cb..244e8d37ed 100644
--- a/usage.c
+++ b/usage.c
@@ -192,7 +192,7 @@ static void show_usage_if_asked_helper(const char *err, ...)
 
 void show_usage_if_asked(int ac, const char **av, const char *err)
 {
-	if (ac == 2 && (!strcmp(av[1], "-h") ||
+	if (ac >= 2 && (!strcmp(av[1], "-h") ||
 			!strcmp(av[1], "--help-all")))
 		show_usage_if_asked_helper(err);
 }
-- 
2.48.1