[PATCH v2 0/4] builtin/refs: introduce subcommand groups
flat view
COOLING13d
From: Patrick Steinhardt <hidden>
Date: 2026-10-02 08:09:53
Revision v2 of 2 in this series.
Revisions (2)
- v1 [diff vs current]
- v2 current
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 (local)
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