Git development
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 0/4] builtin/refs: introduce subcommand groups
Date: Fri, 02 Oct 2026 10:09:45 +0200	[thread overview]
Message-ID: <20261002-b4-pks-parse-options-subcommand-groups-v2-0-3299bee52dea@pks.im> (raw)
In-Reply-To: <20261001-b4-pks-parse-options-subcommand-groups-v1-0-01eb2f4a4c32@pks.im>

Hi,

the git-refs(1) command has grown quite a bunch of different subcommands
by now. These subcommands can easily be grouped into three categories:

  - Operations that span across the whole reference database (migrate,
    verify, optimize).

  - Operations that read references (list, exists).

  - Operations that write references (create, delete, update, rename).

This patch series thus adapts the parse-options subsystem to support
grouping subcommands and then introduces the grouping for git-refs(1).
This results in the following output:

  usage: git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]
     or: git refs verify [--strict] [--verbose]
     or: git refs list [--count=<count>] [--shell|--perl|--python|--tcl]
                                  [(--sort=<key>)...] [--format=<format>]
                                  [--include-root-refs] [--points-at=<object>]
                                  [--merged[=<object>]] [--no-merged[=<object>]]
                                  [--contains[=<object>]] [--no-contains[=<object>]]
                                  [(--exclude=<pattern>)...] [--start-after=<marker>]
                                  [ --stdin | (<pattern>...)]
     or: git refs exists <ref>
     or: git refs optimize [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]
     or: git refs create [--message=<reason>] [--no-deref] [--create-reflog] <ref> <new-value>
     or: git refs delete [--message=<reason>] [--no-deref] <ref> [<old-value>]
     or: git refs update [--message=<reason>] [--no-deref] [--create-reflog] <ref> <new-value> [<old-value>]
     or: git refs rename [--message=<reason>] <old-ref> <new-ref>

  Reference database
      migrate               migrate the reference database to a different format
      verify                verify the consistency of the reference database
      optimize              optimize the reference database

  Reading references
      list                  list references
      exists                check whether a reference exists

  Writing references
      create                create a new reference
      delete                delete a reference
      update                update an existing reference
      rename                rename a reference

I expect that going forward, we'll probably have more use cases where we
can use these new capabilities (e.g. an upcoming git-objects(1) command,
which is going to be the equivalent to git-refs(1)).

Changes in v2:
  - Add a preliminary refactoring for `usage_with_options_internal()` so
    that we don't have to reindent a bunch of its code.
  - Drop `OPT_SUBCOMMAND_H()` and extend `OPT_SUBCOMMAND_F()` instead.
  - Rename `bool first` to `bool shown`.
  - Link to v1: https://patch.msgid.link/20261001-b4-pks-parse-options-subcommand-groups-v1-0-01eb2f4a4c32@pks.im

Thanks!

Patrick

---
Patrick Steinhardt (4):
      parse-options: fix completion format when first option is skipped
      parse-options: extract functions to print single option
      parse-options: allow grouping subcommands
      builtin/refs: introduce subcommand groups

 Documentation/git-refs.adoc                    |   2 +-
 Documentation/technical/api-parse-options.adoc |   4 +-
 builtin/refs.c                                 |  32 +++--
 builtin/remote.c                               |   2 +-
 builtin/stash.c                                |   2 +-
 parse-options.c                                | 176 ++++++++++++++-----------
 parse-options.h                                |   5 +-
 t/helper/test-parse-options.c                  |   4 +-
 t/t0040-parse-options.sh                       |  16 +++
 9 files changed, 150 insertions(+), 93 deletions(-)

Range-diff versus v1:

1:  7ba8a5ca15 ! 1:  10b2249fa6 parse-options: fix completion format when first option is skipped
    @@ parse-options.c: static int show_gitcomp(const struct option *opts, int show_all
      {
      	const struct option *original_opts = opts;
      	int nr_noopts = 0;
    -+	bool first = true;
    ++	bool shown = false;
      
      	for (; opts->type != OPTION_END; opts++) {
      		const char *prefix = "--";
    @@ parse-options.c: static int show_gitcomp(const struct option *opts, int show_all
      		if (starts_with(opts->long_name, "no-"))
      			nr_noopts++;
     -		printf("%s%s%s%s", opts == original_opts ? "" : " ",
    -+		printf("%s%s%s%s", first ? "" : " ",
    ++		printf("%s%s%s%s", shown ? " " : "",
      		       prefix, opts->long_name, suffix);
    -+		first = false;
    ++		shown = true;
      	}
      	show_negated_gitcomp(original_opts, show_all, -1);
      	show_negated_gitcomp(original_opts, show_all, nr_noopts);
2:  8176cf838d < -:  ---------- parse-options: allow grouping subcommands
-:  ---------- > 2:  31e5f08cdb parse-options: extract functions to print single option
-:  ---------- > 3:  20da51f904 parse-options: allow grouping subcommands
3:  9599245895 ! 4:  11cfbe5cae builtin/refs: introduce subcommand groups
    @@ builtin/refs.c: int cmd_refs(int argc,
     -		OPT_SUBCOMMAND("update", &fn, cmd_refs_update),
     -		OPT_SUBCOMMAND("rename", &fn, cmd_refs_rename),
     +		OPT_GROUP(N_("Reference database")),
    -+		OPT_SUBCOMMAND_H("migrate", &fn, cmd_refs_migrate,
    -+				 N_("migrate the reference database to a different format")),
    -+		OPT_SUBCOMMAND_H("verify", &fn, cmd_refs_verify,
    -+				 N_("verify the consistency of the reference database")),
    -+		OPT_SUBCOMMAND_H("optimize", &fn, cmd_refs_optimize,
    -+				 N_("optimize the reference database")),
    ++		OPT_SUBCOMMAND_F("migrate", &fn, cmd_refs_migrate,
    ++				 N_("migrate the reference database to a different format"), 0),
    ++		OPT_SUBCOMMAND_F("verify", &fn, cmd_refs_verify,
    ++				 N_("verify the consistency of the reference database"), 0),
    ++		OPT_SUBCOMMAND_F("optimize", &fn, cmd_refs_optimize,
    ++				 N_("optimize the reference database"), 0),
     +		OPT_GROUP(N_("Reading references")),
    -+		OPT_SUBCOMMAND_H("list", &fn, cmd_refs_list,
    -+				 N_("list references")),
    -+		OPT_SUBCOMMAND_H("exists", &fn, cmd_refs_exists,
    -+				 N_("check whether a reference exists")),
    ++		OPT_SUBCOMMAND_F("list", &fn, cmd_refs_list,
    ++				 N_("list references"), 0),
    ++		OPT_SUBCOMMAND_F("exists", &fn, cmd_refs_exists,
    ++				 N_("check whether a reference exists"), 0),
     +		OPT_GROUP(N_("Writing references")),
    -+		OPT_SUBCOMMAND_H("create", &fn, cmd_refs_create,
    -+				 N_("create a new reference")),
    -+		OPT_SUBCOMMAND_H("delete", &fn, cmd_refs_delete,
    -+				 N_("delete a reference")),
    -+		OPT_SUBCOMMAND_H("update", &fn, cmd_refs_update,
    -+				 N_("update an existing reference")),
    -+		OPT_SUBCOMMAND_H("rename", &fn, cmd_refs_rename,
    -+				 N_("rename a reference")),
    ++		OPT_SUBCOMMAND_F("create", &fn, cmd_refs_create,
    ++				 N_("create a new reference"), 0),
    ++		OPT_SUBCOMMAND_F("delete", &fn, cmd_refs_delete,
    ++				 N_("delete a reference"), 0),
    ++		OPT_SUBCOMMAND_F("update", &fn, cmd_refs_update,
    ++				 N_("update an existing reference"), 0),
    ++		OPT_SUBCOMMAND_F("rename", &fn, cmd_refs_rename,
    ++				 N_("rename a reference"), 0),
      		OPT_END(),
      	};
      

---
base-commit: a018953688f1b10bddf91bff8747068f5f4746a4
change-id: 20261001-b4-pks-parse-options-subcommand-groups-59b3f27da06c


  parent reply	other threads:[~2026-10-02  8:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01 10:13 [PATCH 0/3] builtin/refs: introduce subcommand groups Patrick Steinhardt
2026-10-01 10:13 ` [PATCH 1/3] parse-options: fix completion format when first option is skipped Patrick Steinhardt
2026-10-01 17:38   ` Junio C Hamano
2026-10-02  7:19     ` Patrick Steinhardt
2026-10-01 10:13 ` [PATCH 2/3] parse-options: allow grouping subcommands Patrick Steinhardt
2026-10-01 17:46   ` Junio C Hamano
2026-10-02  7:19     ` Patrick Steinhardt
2026-10-01 10:13 ` [PATCH 3/3] builtin/refs: introduce subcommand groups Patrick Steinhardt
2026-10-01 17:46   ` Junio C Hamano
2026-10-02  8:09 ` Patrick Steinhardt [this message]
2026-10-02  8:09   ` [PATCH v2 1/4] parse-options: fix completion format when first option is skipped Patrick Steinhardt
2026-10-02  8:09   ` [PATCH v2 2/4] parse-options: extract functions to print single option Patrick Steinhardt
2026-10-02  8:09   ` [PATCH v2 3/4] parse-options: allow grouping subcommands Patrick Steinhardt
2026-10-02  8:09   ` [PATCH v2 4/4] builtin/refs: introduce subcommand groups Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261002-b4-pks-parse-options-subcommand-groups-v2-0-3299bee52dea@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox