git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/5] parseopt: extract subcommand handling from parse_options_step()

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 8, 2026, 23:40 UTC
Message-ID
<xmqq1phtao03.fsf@gitster.g>
In-Reply-To
<SY0P300MB0801422323C4C4185B9617A1CE78A@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>
Jiamu Sun <39@barroit.sh> writes:
> -static enum parse_opt_result parse_subcommand(const char *arg,
> -					      const struct option *options)

So, this function used to return either PARSE_OPT_SUBCOMMAND or PARSE_OPT_UNKNOWN, and the caller (in an "switch ()" statement in the parse_options_step() we see below) expected only these two. We now instead ...

> +static int parse_subcommand(const char *arg, const struct option *options)

... make it return either 0 (success - we found a subcommand) or -1 (failure - we did not). The updated caller does use the return value in "if ()" condition to return early when we found a subcommand successfully, which is a lot more straight-forward than the original "switch()". The original is even worse in that it enumerates other PARSE_OPT_* values that are possible at the time of writing it, instead of catching everything else with "default:", which makes the switch() statement a maintenance burden. Getting rid of that switch and clarifying that there are only two possible outcome from this function alone is a good enough justification to have this clean-up patch. Very well done.

Editing the hunk to show only the postimage reveals that the new implementation has CodingGuidelines violation ...

Show 7 quoted lines
>  {
> +	for (; options->type != OPTION_END; options++) {
> +		if (options->type != OPTION_SUBCOMMAND ||
> +		    strcmp(options->long_name, arg))
> +			continue;
>  
> +		parse_opt_subcommand_fn **opt_val = options->value;

... here. Move the variable definition up in the block introduced by the for(;;) statement, perhaps?

Show 8 quoted lines
> +		*opt_val = options->subcommand_fn;
> +
> +		return 0;
> +	}
> +
> +	return -1;
> +}
> +

And the part of the caller of parse_subcommand() that used to be the switch() statement in the parse_options_step() is now extracted into yet another helper function here.

Show 16 quoted lines
> +static enum parse_opt_result handle_subcommand(struct parse_opt_ctx_t *ctx,
> +					       const char *arg,
> +					       const struct option *options,
> +					       const char * const usagestr[])
> +{
> +	int err = parse_subcommand(arg, options);
> +
> +	if (!err)
> +		return PARSE_OPT_SUBCOMMAND;
> +
> +	/*
> +	 * arg is neither a short or long option nor a subcommand.  Since this
> +	 * command has a default operation mode, we have to treat this arg and
> +	 * all remaining args as args meant to that default operation mode.
> +	 * So we are done parsing.
> +	 */

Thanks to being a small helper function, we lost two levels of indentation which made this comment a lot more readable with reflowing the lines ;-)

Show 6 quoted lines
> +	if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
> +		return PARSE_OPT_DONE;
> +
> +	error(_("unknown subcommand: `%s'"), arg);
> +	usage_with_options(usagestr, options);
>  }

It is clear that there is no unintended behaviour change around this helper function and parse_subcommand(). Very nice.

Show 16 quoted lines
> @@ -990,37 +1016,16 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
>  		if (*arg != '-' || !arg[1]) {
>  			if (parse_nodash_opt(ctx, arg, options) == 0)
>  				continue;
> +
>  			if (!ctx->has_subcommands) {
>  				if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
>  					return PARSE_OPT_NON_OPTION;
>  				ctx->out[ctx->cpidx++] = ctx->argv[0];
>  				continue;
> +
> +			} else {
> +				return handle_subcommand(ctx, arg,
> +							 options, usagestr);
>  			}
>  		}

Editing the hunk to only show the postimage shows us that the blank line at the end of the "if ()" block is funny. Drop it. Or even better, as the block either returns or continues anyway, lose the "else" block, perhaps? Which will make the above read like so:

			if (!ctx->has_subcommands) {
				if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
                                	return PARSE_OPT_NON_OPTION;
				ctx->out[ctx->cpidx++] = ctx->argv[0];
				continue;
			}
                        return has_subcommands(ctx, arg, options, usagestr);
or swapping the logic the other way around, i.e.,
			if (ctx->has_subcommands)
				return has_subcommands(ctx, arg,
						       options, usagestr);
                        if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
                                return PARSE_OPT_NON_OPTION;
                        ctx->out[ctx->cpidx++] = ctx->argv[0];
                        continue;
may make the result even easier to read, perhaps?
Previous: Jiamu SunNext: Jiamu Sun
Message 3 of 96 in “parseopt: add subcommand autocorrection”
  1. 0/5 parseopt: add subcommand autocorrectionJiamu Sun, Mar 8, 2026
  2. 1/5 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Mar 8, 2026
  3. Junio C HamanoMar 8, 2026
  4. Jiamu SunMar 9, 2026
  5. 2/5 help: refactor command autocorrection handlingJiamu Sun, Mar 8, 2026
  6. Junio C HamanoMar 8, 2026
  7. Jiamu SunMar 9, 2026
  8. 3/5 parseopt: autocorrect mistyped subcommandsJiamu Sun, Mar 8, 2026
  9. Junio C HamanoMar 9, 2026
  10. Jiamu SunMar 9, 2026
  11. 4/5 parseopt: enable subcommand autocorrect for remote and notesJiamu Sun, Mar 8, 2026
  12. 5/5 help: add tests for subcommand autocorrectionJiamu Sun, Mar 8, 2026
  13. Aaron PlattnerMar 11, 2026
  14. Jiamu SunMar 11, 2026
  15. Junio C HamanoMar 12, 2026
  16. Junio C HamanoMar 8, 2026
  17. Jiamu SunMar 8, 2026
  18. 0/5 parseopt: add subcommand autocorrectionJiamu Sun, Mar 8, 2026
  19. 1/5 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Mar 8, 2026
  20. 2/5 help: refactor command autocorrection handlingJiamu Sun, Mar 8, 2026
  21. 3/5 parseopt: autocorrect mistyped subcommandsJiamu Sun, Mar 8, 2026
  22. 4/5 parseopt: enable subcommand autocorrect for remote and notesJiamu Sun, Mar 8, 2026
  23. 5/5 help: add tests for subcommand autocorrectionJiamu Sun, Mar 8, 2026
  24. 0/8 parseopt: add subcommand autocorrectionJiamu Sun, Mar 10, 2026
  25. 1/8 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Mar 10, 2026
  26. Karthik NayakMar 10, 2026
  27. Jiamu SunMar 11, 2026
  28. Junio C HamanoMar 11, 2026
  29. Junio C HamanoMar 11, 2026
  30. Jiamu SunMar 11, 2026
  31. 2/8 help: make autocorrect handling reusableJiamu Sun, Mar 10, 2026
  32. Karthik NayakMar 10, 2026
  33. Junio C HamanoMar 10, 2026
  34. Jiamu SunMar 11, 2026
  35. Jiamu SunMar 11, 2026
  36. 3/8 help: move tty check for autocorrection to autocorrect.cJiamu Sun, Mar 10, 2026
  37. Karthik NayakMar 10, 2026
  38. Jiamu SunMar 11, 2026
  39. Jiamu SunMar 12, 2026
  40. 4/8 autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINTONLYJiamu Sun, Mar 10, 2026
  41. Karthik NayakMar 10, 2026
  42. Jiamu SunMar 11, 2026
  43. 5/8 autocorrect: provide config resolution APIJiamu Sun, Mar 10, 2026
  44. Karthik NayakMar 10, 2026
  45. 6/8 parseopt: autocorrect mistyped subcommandsJiamu Sun, Mar 10, 2026
  46. Junio C HamanoMar 10, 2026
  47. Jiamu SunMar 11, 2026
  48. Jiamu SunMar 11, 2026
  49. Junio C HamanoMar 12, 2026
  50. Jiamu SunMar 12, 2026
  51. 7/8 parseopt: enable subcommand autocorrection for git-remote and git-notesJiamu Sun, Mar 10, 2026
  52. 8/8 help: add tests for subcommand autocorrectionJiamu Sun, Mar 10, 2026
  53. Junio C HamanoMar 11, 2026
  54. Jiamu SunMar 11, 2026
  55. 00/10 parseopt: add subcommand autocorrectionJiamu Sun, Mar 16, 2026
  56. 01/10 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Mar 16, 2026
  57. 02/10 help: make autocorrect handling reusableJiamu Sun, Mar 16, 2026
  58. 03/10 help: move tty check for autocorrection to autocorrect.cJiamu Sun, Mar 16, 2026
  59. 04/10 autocorrect: use mode and delay instead of magic numbersJiamu Sun, Mar 16, 2026
  60. 05/10 autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINTJiamu Sun, Mar 16, 2026
  61. 06/10 autocorrect: provide config resolution APIJiamu Sun, Mar 16, 2026
  62. 07/10 parseopt: autocorrect mistyped subcommandsJiamu Sun, Mar 16, 2026
  63. Junio C HamanoMar 16, 2026
  64. Jiamu SunMar 17, 2026
  65. Junio C HamanoApr 15, 2026
  66. Jiamu SunApr 16, 2026
  67. 08/10 parseopt: enable subcommand autocorrection for git-remote and git-notesJiamu Sun, Mar 16, 2026
  68. 09/10 parseopt: add tests for subcommand autocorrectionJiamu Sun, Mar 16, 2026
  69. 10/10 doc: document autocorrect APIJiamu Sun, Mar 16, 2026
  70. 00/10 parseopt: add subcommand autocorrectionJiamu Sun, Apr 22, 2026
  71. 02/10 help: make autocorrect handling reusableJiamu Sun, Apr 22, 2026
  72. 01/10 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Apr 22, 2026
  73. 03/10 help: move tty check for autocorrection to autocorrect.cJiamu Sun, Apr 22, 2026
  74. 04/10 autocorrect: use mode and delay instead of magic numbersJiamu Sun, Apr 22, 2026
  75. 05/10 autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINTJiamu Sun, Apr 22, 2026
  76. 06/10 autocorrect: provide config resolution APIJiamu Sun, Apr 22, 2026
  77. 07/10 parseopt: autocorrect mistyped subcommandsJiamu Sun, Apr 22, 2026
  78. 08/10 parseopt: enable subcommand autocorrection for git-remote and git-notesJiamu Sun, Apr 22, 2026
  79. 09/10 parseopt: add tests for subcommand autocorrectionJiamu Sun, Apr 22, 2026
  80. 10/10 doc: document autocorrect APIJiamu Sun, Apr 22, 2026
  81. Junio C HamanoApr 23, 2026
  82. Jiamu SunApr 23, 2026
  83. 00/10 parseopt: add subcommand autocorrectionJiamu Sun, Apr 23, 2026
  84. 01/10 parseopt: extract subcommand handling from parse_options_step()Jiamu Sun, Apr 23, 2026
  85. 02/10 help: make autocorrect handling reusableJiamu Sun, Apr 23, 2026
  86. 03/10 help: move tty check for autocorrection to autocorrect.cJiamu Sun, Apr 23, 2026
  87. 04/10 autocorrect: use mode and delay instead of magic numbersJiamu Sun, Apr 23, 2026
  88. 06/10 autocorrect: provide config resolution APIJiamu Sun, Apr 23, 2026
  89. 10/10 doc: document autocorrect APIJiamu Sun, Apr 23, 2026
  90. 05/10 autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINTJiamu Sun, Apr 23, 2026
  91. 07/10 parseopt: autocorrect mistyped subcommandsJiamu Sun, Apr 23, 2026
  92. 08/10 parseopt: enable subcommand autocorrection for git-remote and git-notesJiamu Sun, Apr 23, 2026
  93. 09/10 parseopt: add tests for subcommand autocorrectionJiamu Sun, Apr 23, 2026
  94. Junio C HamanoMay 11, 2026
  95. Jiamu SunMay 15, 2026
  96. Junio C HamanoJun 6, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.