{"thread":{"id":"62542","subject":"[PATCH] builtin: pass repository to sub commands","startedAt":"2024-11-25T14:55:42Z","lastAt":"2024-11-27T12:23:09Z","messageCount":12,"participants":["Karthik Nayak","Christian Couder","Patrick Steinhardt","karthik nayak","shejialuo","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"508100","messageId":"20241125-374-add-repository-to-subsubcommands-v1-1-637a5e22ba48@gmail.com","threadId":"62542","inReplyTo":null,"subject":"[PATCH] builtin: pass repository to sub commands","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-25T14:55:30Z","receivedAt":"2024-11-25T14:55:42Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"In 9b1cb5070f (builtin: add a repository parameter for builtin\nfunctions, 2024-09-13) the repository was passed down to all builtin\ncommands. This allowed the repository to be passed down to lower layers\nwithout depending on the global `the_repository` variable.\n\nContinue this work by also passing down the repository parameter from\nthe command to sub-commands. This will help pass down the repository to\nother subsystems and cleanup usage of global variables like\n'the_repository' and 'the_hash_algo'.\n\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\nThis patch was part of my series to clean up the midx.c and midx-write.c\nfiles from using global variables [1]. Since this patch stands on its own,\nI've split it from the series. This should help merging this quicker\nsince it affects a lot more files but is isolated to one patch. \n\nI will re-send a new version of the series to depend on this patch. \n\nThis patch conflicts with 'gitster/bf/set-head-symref' on seen. But it is \nnot a dependency and the resolution should be simple enough. Happy to\nresend after merging that in if needed. \n\n[1]: https://lore.kernel.org/all/20241115-374-refactor-midx-c-and-midx-write-c-to-not-depend-on-global-state-v1-0-761f8a2c7775@gmail.com/\n---\n builtin/bisect.c              | 32 +++++++++++++++++++-----------\n builtin/bundle.c              | 16 +++++++++------\n builtin/commit-graph.c        | 10 ++++++----\n builtin/config.c              | 25 ++++++++++++++---------\n builtin/gc.c                  | 21 ++++++++++++--------\n builtin/hook.c                |  7 ++++---\n builtin/multi-pack-index.c    | 16 +++++++++------\n builtin/notes.c               | 36 +++++++++++++++++++++------------\n builtin/reflog.c              | 17 ++++++++++------\n builtin/refs.c                | 10 ++++++----\n builtin/remote.c              | 34 +++++++++++++++++++++-----------\n builtin/sparse-checkout.c     | 25 ++++++++++++++---------\n builtin/stash.c               | 39 +++++++++++++++++++++++-------------\n builtin/submodule--helper.c   | 46 ++++++++++++++++++++++++++++---------------\n builtin/worktree.c            | 28 ++++++++++++++++----------\n parse-options.h               |  4 +++-\n t/helper/test-parse-options.c |  8 +++++---\n 17 files changed, 239 insertions(+), 135 deletions(-)\n\ndiff --git a/builtin/bisect.c b/builtin/bisect.c\nindex 21d17a6c1a83e51fb82b53703b95d89bd9028830..8166d4abf532fbc95aaac71198e9722684ccf7f5 100644\n--- a/builtin/bisect.c\n+++ b/builtin/bisect.c\n@@ -1312,7 +1312,8 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \treturn res;\n }\n \n-static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tif (argc > 1)\n \t\treturn error(_(\"'%s' requires either no argument or a commit\"),\n@@ -1320,7 +1321,8 @@ static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNU\n \treturn bisect_reset(argc ? argv[0] : NULL);\n }\n \n-static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1333,7 +1335,8 @@ static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNU\n \treturn res;\n }\n \n-static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1344,7 +1347,8 @@ static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNU\n \treturn res;\n }\n \n-static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)\n+static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix,\n+\t\t\t    struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1358,12 +1362,15 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref\n \treturn res;\n }\n \n-static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, const char *prefix UNUSED)\n+static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED,\n+\t\t\t   const char *prefix UNUSED,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \treturn bisect_log();\n }\n \n-static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t      struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1376,7 +1383,8 @@ static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UN\n \treturn res;\n }\n \n-static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t    struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1388,7 +1396,8 @@ static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUS\n \treturn res;\n }\n \n-static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t\t struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1399,7 +1408,8 @@ static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix\n \treturn res;\n }\n \n-static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1415,7 +1425,7 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE\n int cmd_bisect(int argc,\n \t       const char **argv,\n \t       const char *prefix,\n-\t       struct repository *repo UNUSED)\n+\t       struct repository *repo)\n {\n \tint res = 0;\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -1451,7 +1461,7 @@ int cmd_bisect(int argc,\n \t} else {\n \t\targc--;\n \t\targv++;\n-\t\tres = fn(argc, argv, prefix);\n+\t\tres = fn(argc, argv, prefix, repo);\n \t}\n \n \treturn is_bisect_success(res) ? 0 : -res;\ndiff --git a/builtin/bundle.c b/builtin/bundle.c\nindex 127518c2a8d3c4ec0bde62f1932e964ce9bcf66f..3f14754197c847e7a4e98b607c1a24df2b053daf 100644\n--- a/builtin/bundle.c\n+++ b/builtin/bundle.c\n@@ -67,7 +67,8 @@ static int parse_options_cmd_bundle(int argc,\n \treturn argc;\n }\n \n-static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_create(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED) {\n \tstruct strvec pack_opts = STRVEC_INIT;\n \tint version = -1;\n \tint ret;\n@@ -123,7 +124,8 @@ static int open_bundle(const char *path, struct bundle_header *header,\n \treturn read_bundle_header(path, header);\n }\n \n-static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_verify(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint quiet = 0;\n@@ -164,7 +166,8 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {\n \treturn ret;\n }\n \n-static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix,\n+\t\t\t\t struct repository *repo UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint ret;\n@@ -189,7 +192,8 @@ static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix\n \treturn ret;\n }\n \n-static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix,\n+\t\t\t       struct repository *repo UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint ret;\n@@ -231,7 +235,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)\n int cmd_bundle(int argc,\n \t       const char **argv,\n \t       const char *prefix,\n-\t       struct repository *repo UNUSED)\n+\t       struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option options[] = {\n@@ -247,5 +251,5 @@ int cmd_bundle(int argc,\n \n \tpacket_trace_identity(\"bundle\");\n \n-\treturn !!fn(argc, argv, prefix);\n+\treturn !!fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 7c991db6eb48ad6e935727a079abac02bb358f8a..bd70d052e706b6e34b5aaaceef158c63ea4863d5 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -62,7 +62,8 @@ static struct option *add_common_options(struct option *to)\n \treturn parse_options_concat(common_opts, to);\n }\n \n-static int graph_verify(int argc, const char **argv, const char *prefix)\n+static int graph_verify(int argc, const char **argv, const char *prefix,\n+\t\t\tstruct repository *repo UNUSED)\n {\n \tstruct commit_graph *graph = NULL;\n \tstruct object_directory *odb = NULL;\n@@ -214,7 +215,8 @@ static int git_commit_graph_write_config(const char *var, const char *value,\n \treturn 0;\n }\n \n-static int graph_write(int argc, const char **argv, const char *prefix)\n+static int graph_write(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tstruct string_list pack_indexes = STRING_LIST_INIT_DUP;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -333,7 +335,7 @@ static int graph_write(int argc, const char **argv, const char *prefix)\n int cmd_commit_graph(int argc,\n \t\t     const char **argv,\n \t\t     const char *prefix,\n-\t\t     struct repository *repo UNUSED)\n+\t\t     struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option builtin_commit_graph_options[] = {\n@@ -352,5 +354,5 @@ int cmd_commit_graph(int argc,\n \t\t\t     builtin_commit_graph_usage, 0);\n \tFREE_AND_NULL(options);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/config.c b/builtin/config.c\nindex cba702210815b716a5c6c93ebb69d8c485901e43..16e6e3055598f1355714dc6de458b662870214c0 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -826,7 +826,8 @@ static void display_options_init(struct config_display_options *opts)\n \t}\n }\n \n-static int cmd_config_list(int argc, const char **argv, const char *prefix)\n+static int cmd_config_list(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n@@ -861,7 +862,8 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int cmd_config_get(int argc, const char **argv, const char *prefix)\n+static int cmd_config_get(int argc, const char **argv, const char *prefix,\n+\t\t\t  struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n@@ -915,7 +917,8 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_set(int argc, const char **argv, const char *prefix)\n+static int cmd_config_set(int argc, const char **argv, const char *prefix,\n+\t\t\t  struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tconst char *value_pattern = NULL, *comment_arg = NULL;\n@@ -973,7 +976,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_unset(int argc, const char **argv, const char *prefix)\n+static int cmd_config_unset(int argc, const char **argv, const char *prefix,\n+\t\t\t    struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tconst char *value_pattern = NULL;\n@@ -1010,7 +1014,8 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)\n+static int cmd_config_rename_section(int argc, const char **argv, const char *prefix,\n+\t\t\t\t     struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1039,7 +1044,8 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr\n \treturn ret;\n }\n \n-static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)\n+static int cmd_config_remove_section(int argc, const char **argv, const char *prefix,\n+\t\t\t\t     struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1099,7 +1105,8 @@ static int show_editor(struct config_location_options *opts)\n \treturn 0;\n }\n \n-static int cmd_config_edit(int argc, const char **argv, const char *prefix)\n+static int cmd_config_edit(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1395,7 +1402,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)\n int cmd_config(int argc,\n \t       const char **argv,\n \t       const char *prefix,\n-\t       struct repository *repo UNUSED)\n+\t       struct repository *repo)\n {\n \tparse_opt_subcommand_fn *subcommand = NULL;\n \tstruct option subcommand_opts[] = {\n@@ -1422,7 +1429,7 @@ int cmd_config(int argc,\n \tif (subcommand) {\n \t\targc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage,\n \t\t       PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT);\n-\t\treturn subcommand(argc, argv, prefix);\n+\t\treturn subcommand(argc, argv, prefix, repo);\n \t}\n \n \treturn cmd_config_actions(argc, argv, prefix);\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex d52735354c9f87ba4e8acb593dd11aa0482223e1..a55f54c09f7c249a35e42321d8f34bb379c20d57 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -1561,7 +1561,8 @@ static int task_option_parse(const struct option *opt UNUSED,\n \treturn 0;\n }\n \n-static int maintenance_run(int argc, const char **argv, const char *prefix)\n+static int maintenance_run(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tint i;\n \tstruct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;\n@@ -1623,7 +1624,8 @@ static char const * const builtin_maintenance_register_usage[] = {\n \tNULL\n };\n \n-static int maintenance_register(int argc, const char **argv, const char *prefix)\n+static int maintenance_register(int argc, const char **argv, const char *prefix,\n+\t\t\t\tstruct repository *repo UNUSED)\n {\n \tchar *config_file = NULL;\n \tstruct option options[] = {\n@@ -1687,7 +1689,8 @@ static char const * const builtin_maintenance_unregister_usage[] = {\n \tNULL\n };\n \n-static int maintenance_unregister(int argc, const char **argv, const char *prefix)\n+static int maintenance_unregister(int argc, const char **argv, const char *prefix,\n+\t\t\t\t  struct repository *repo UNUSED)\n {\n \tint force = 0;\n \tchar *config_file = NULL;\n@@ -2917,7 +2920,8 @@ static const char *const builtin_maintenance_start_usage[] = {\n \tNULL\n };\n \n-static int maintenance_start(int argc, const char **argv, const char *prefix)\n+static int maintenance_start(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo)\n {\n \tstruct maintenance_start_opts opts = { 0 };\n \tstruct option options[] = {\n@@ -2940,7 +2944,7 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)\n \tif (update_background_schedule(&opts, 1))\n \t\tdie(_(\"failed to set up maintenance schedule\"));\n \n-\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))\n+\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, repo))\n \t\twarning(_(\"failed to add repo to global config\"));\n \treturn 0;\n }\n@@ -2950,7 +2954,8 @@ static const char *const builtin_maintenance_stop_usage[] = {\n \tNULL\n };\n \n-static int maintenance_stop(int argc, const char **argv, const char *prefix)\n+static int maintenance_stop(int argc, const char **argv, const char *prefix,\n+\t\t\t    struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -2970,7 +2975,7 @@ static const char * const builtin_maintenance_usage[] = {\n int cmd_maintenance(int argc,\n \t\t    const char **argv,\n \t\t    const char *prefix,\n-\t\t    struct repository *repo UNUSED)\n+\t\t    struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option builtin_maintenance_options[] = {\n@@ -2984,5 +2989,5 @@ int cmd_maintenance(int argc,\n \n \targc = parse_options(argc, argv, prefix, builtin_maintenance_options,\n \t\t\t     builtin_maintenance_usage, 0);\n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/hook.c b/builtin/hook.c\nindex 367ef3e0b893fa16756880395151a82ed053acd8..672d2e37e845a2118aca1c4417a837138c250590 100644\n--- a/builtin/hook.c\n+++ b/builtin/hook.c\n@@ -19,7 +19,8 @@ static const char * const builtin_hook_run_usage[] = {\n \tNULL\n };\n \n-static int run(int argc, const char **argv, const char *prefix)\n+static int run(int argc, const char **argv, const char *prefix,\n+\t       struct repository *repo UNUSED)\n {\n \tint i;\n \tstruct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;\n@@ -70,7 +71,7 @@ static int run(int argc, const char **argv, const char *prefix)\n int cmd_hook(int argc,\n \t     const char **argv,\n \t     const char *prefix,\n-\t     struct repository *repo UNUSED)\n+\t     struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option builtin_hook_options[] = {\n@@ -81,5 +82,5 @@ int cmd_hook(int argc,\n \targc = parse_options(argc, argv, NULL, builtin_hook_options,\n \t\t\t     builtin_hook_usage, 0);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c\nindex d159ed1314d912a390ed725659b3abe7c821b83f..85e40a4b6d3e47e9ec1ec27c094455e5ba75b5b0 100644\n--- a/builtin/multi-pack-index.c\n+++ b/builtin/multi-pack-index.c\n@@ -119,7 +119,8 @@ static void read_packs_from_stdin(struct string_list *to)\n }\n \n static int cmd_multi_pack_index_write(int argc, const char **argv,\n-\t\t\t\t      const char *prefix)\n+\t\t\t\t      const char *prefix,\n+\t\t\t\t      struct repository *repo UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_write_options[] = {\n@@ -183,7 +184,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_verify(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix,\n+\t\t\t\t       struct repository *repo UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_verify_options[] = {\n@@ -210,7 +212,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_expire(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix,\n+\t\t\t\t       struct repository *repo UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_expire_options[] = {\n@@ -237,7 +240,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_repack(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix,\n+\t\t\t\t       struct repository *repo UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_repack_options[] = {\n@@ -271,7 +275,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,\n int cmd_multi_pack_index(int argc,\n \t\t\t const char **argv,\n \t\t\t const char *prefix,\n-\t\t\t struct repository *repo UNUSED)\n+\t\t\t struct repository *repo)\n {\n \tint res;\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -297,7 +301,7 @@ int cmd_multi_pack_index(int argc,\n \t\t\t     builtin_multi_pack_index_usage, 0);\n \tFREE_AND_NULL(options);\n \n-\tres = fn(argc, argv, prefix);\n+\tres = fn(argc, argv, prefix, repo);\n \n \tfree(opts.object_dir);\n \treturn res;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 72c8a51cfacf72e1f115774487311b3d4464d204..d051abf6dff8f2bce193fd52b4beda5060af3972 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -431,7 +431,8 @@ static struct notes_tree *init_notes_check(const char *subcommand,\n \treturn t;\n }\n \n-static int list(int argc, const char **argv, const char *prefix)\n+static int list(int argc, const char **argv, const char *prefix,\n+\t\tstruct repository *repo UNUSED)\n {\n \tstruct notes_tree *t;\n \tstruct object_id object;\n@@ -468,9 +469,11 @@ static int list(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int append_edit(int argc, const char **argv, const char *prefix);\n+static int append_edit(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED);\n \n-static int add(int argc, const char **argv, const char *prefix)\n+static int add(int argc, const char **argv, const char *prefix,\n+\t       struct repository *repo)\n {\n \tint force = 0, allow_empty = 0;\n \tconst char *object_ref;\n@@ -543,7 +546,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\t * argv[0-1].\n \t\t\t */\n \t\t\targv[0] = \"edit\";\n-\t\t\treturn append_edit(argc, argv, prefix);\n+\t\t\treturn append_edit(argc, argv, prefix, repo);\n \t\t}\n \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n \t\t\toid_to_hex(&object));\n@@ -569,7 +572,8 @@ static int add(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int copy(int argc, const char **argv, const char *prefix)\n+static int copy(int argc, const char **argv, const char *prefix,\n+\t\tstruct repository *repo UNUSED)\n {\n \tint retval = 0, force = 0, from_stdin = 0;\n \tconst struct object_id *from_note, *note;\n@@ -646,7 +650,8 @@ static int copy(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int append_edit(int argc, const char **argv, const char *prefix)\n+static int append_edit(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tint allow_empty = 0;\n \tconst char *object_ref;\n@@ -749,7 +754,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int show(int argc, const char **argv, const char *prefix)\n+static int show(int argc, const char **argv, const char *prefix,\n+\t\tstruct repository *repo UNUSED)\n {\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n@@ -875,7 +881,8 @@ static int git_config_get_notes_strategy(const char *key,\n \treturn 0;\n }\n \n-static int merge(int argc, const char **argv, const char *prefix)\n+static int merge(int argc, const char **argv, const char *prefix,\n+\t\t struct repository *repo UNUSED)\n {\n \tstruct strbuf remote_ref = STRBUF_INIT, msg = STRBUF_INIT;\n \tstruct object_id result_oid;\n@@ -1016,7 +1023,8 @@ static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag\n \treturn (flag & IGNORE_MISSING) ? 0 : status;\n }\n \n-static int remove_cmd(int argc, const char **argv, const char *prefix)\n+static int remove_cmd(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tunsigned flag = 0;\n \tint from_stdin = 0;\n@@ -1059,7 +1067,8 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int prune(int argc, const char **argv, const char *prefix)\n+static int prune(int argc, const char **argv, const char *prefix,\n+\t\t struct repository *repo UNUSED)\n {\n \tstruct notes_tree *t;\n \tint show_only = 0, verbose = 0;\n@@ -1088,7 +1097,8 @@ static int prune(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int get_ref(int argc, const char **argv, const char *prefix)\n+static int get_ref(int argc, const char **argv, const char *prefix,\n+\t\t   struct repository *repo UNUSED)\n {\n \tstruct option options[] = { OPT_END() };\n \tchar *notes_ref;\n@@ -1109,7 +1119,7 @@ static int get_ref(int argc, const char **argv, const char *prefix)\n int cmd_notes(int argc,\n \t      const char **argv,\n \t      const char *prefix,\n-\t      struct repository *repo UNUSED)\n+\t      struct repository *repo)\n {\n \tconst char *override_notes_ref = NULL;\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -1148,5 +1158,5 @@ int cmd_notes(int argc,\n \t\tstrbuf_release(&sb);\n \t}\n \n-\treturn !!fn(argc, argv, prefix);\n+\treturn !!fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/reflog.c b/builtin/reflog.c\nindex 22df6834f71098ab8378e4423967f0fb87858340..5a0c22f2f7e58733ce636619f3f19265b394bde5 100644\n--- a/builtin/reflog.c\n+++ b/builtin/reflog.c\n@@ -234,7 +234,8 @@ static int expire_total_callback(const struct option *opt,\n \treturn 0;\n }\n \n-static int cmd_reflog_show(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_show(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -253,7 +254,8 @@ static int show_reflog(const char *refname, void *cb_data UNUSED)\n \treturn 0;\n }\n \n-static int cmd_reflog_list(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_list(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -270,7 +272,8 @@ static int cmd_reflog_list(int argc, const char **argv, const char *prefix)\n \treturn refs_for_each_reflog(ref_store, show_reflog, NULL);\n }\n \n-static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tstruct cmd_reflog_expire_cb cmd = { 0 };\n \ttimestamp_t now = time(NULL);\n@@ -394,7 +397,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n \treturn status;\n }\n \n-static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_delete(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tint i, status = 0;\n \tunsigned int flags = 0;\n@@ -424,7 +428,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)\n \treturn status;\n }\n \n-static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_exists(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -467,7 +472,7 @@ int cmd_reflog(int argc,\n \t\t\t     PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |\n \t\t\t     PARSE_OPT_KEEP_UNKNOWN_OPT);\n \tif (fn)\n-\t\treturn fn(argc - 1, argv + 1, prefix);\n+\t\treturn fn(argc - 1, argv + 1, prefix, repository);\n \telse\n \t\treturn cmd_log_reflog(argc, argv, prefix, repository);\n }\ndiff --git a/builtin/refs.c b/builtin/refs.c\nindex 24978a7b7b081ac6ed8ca99016f201d34c0639f8..3502980d21d055d8fc5ef36d2165aae61bc4db62 100644\n--- a/builtin/refs.c\n+++ b/builtin/refs.c\n@@ -12,7 +12,8 @@\n #define REFS_VERIFY_USAGE \\\n \tN_(\"git refs verify [--strict] [--verbose]\")\n \n-static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)\n+static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n+\t\t\t    struct repository *repo UNUSED)\n {\n \tconst char * const migrate_usage[] = {\n \t\tREFS_MIGRATE_USAGE,\n@@ -63,7 +64,8 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)\n \treturn err;\n }\n \n-static int cmd_refs_verify(int argc, const char **argv, const char *prefix)\n+static int cmd_refs_verify(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;\n \tconst char * const verify_usage[] = {\n@@ -93,7 +95,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix)\n int cmd_refs(int argc,\n \t     const char **argv,\n \t     const char *prefix,\n-\t     struct repository *repo UNUSED)\n+\t     struct repository *repo)\n {\n \tconst char * const refs_usage[] = {\n \t\tREFS_MIGRATE_USAGE,\n@@ -108,5 +110,5 @@ int cmd_refs(int argc,\n \t};\n \n \targc = parse_options(argc, argv, prefix, opts, refs_usage, 0);\n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 909360096513fc72445f54b13ee92d7a95111ce1..1ad3e70a6b438a3c4446b16c02dc5c23c7fa14be 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -155,7 +155,8 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)\n \treturn 0;\n }\n \n-static int add(int argc, const char **argv, const char *prefix)\n+static int add(int argc, const char **argv, const char *prefix,\n+\t       struct repository *repo UNUSED)\n {\n \tint fetch = 0, fetch_tags = TAGS_DEFAULT;\n \tunsigned mirror = MIRROR_NONE;\n@@ -706,7 +707,8 @@ static void handle_push_default(const char* old_name, const char* new_name)\n }\n \n \n-static int mv(int argc, const char **argv, const char *prefix)\n+static int mv(int argc, const char **argv, const char *prefix,\n+\t      struct repository *repo UNUSED)\n {\n \tint show_progress = isatty(2);\n \tstruct option options[] = {\n@@ -881,7 +883,8 @@ static int mv(int argc, const char **argv, const char *prefix)\n \treturn result;\n }\n \n-static int rm(int argc, const char **argv, const char *prefix)\n+static int rm(int argc, const char **argv, const char *prefix,\n+\t      struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -1303,7 +1306,8 @@ static int show_all(void)\n \treturn result;\n }\n \n-static int show(int argc, const char **argv, const char *prefix)\n+static int show(int argc, const char **argv, const char *prefix,\n+\t\tstruct repository *repo UNUSED)\n {\n \tint no_query = 0, result = 0, query_flag = 0;\n \tstruct option options[] = {\n@@ -1399,7 +1403,8 @@ static int show(int argc, const char **argv, const char *prefix)\n \treturn result;\n }\n \n-static int set_head(int argc, const char **argv, const char *prefix)\n+static int set_head(int argc, const char **argv, const char *prefix,\n+\t\t    struct repository *repo UNUSED)\n {\n \tint i, opt_a = 0, opt_d = 0, result = 0;\n \tstruct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;\n@@ -1503,7 +1508,8 @@ static int prune_remote(const char *remote, int dry_run)\n \treturn result;\n }\n \n-static int prune(int argc, const char **argv, const char *prefix)\n+static int prune(int argc, const char **argv, const char *prefix,\n+\t\t struct repository *repo UNUSED)\n {\n \tint dry_run = 0, result = 0;\n \tstruct option options[] = {\n@@ -1534,7 +1540,8 @@ static int get_remote_default(const char *key, const char *value UNUSED,\n \treturn 0;\n }\n \n-static int update(int argc, const char **argv, const char *prefix)\n+static int update(int argc, const char **argv, const char *prefix,\n+\t\t  struct repository *repo UNUSED)\n {\n \tint i, prune = -1;\n \tstruct option options[] = {\n@@ -1616,7 +1623,8 @@ static int set_remote_branches(const char *remotename, const char **branches,\n \treturn 0;\n }\n \n-static int set_branches(int argc, const char **argv, const char *prefix)\n+static int set_branches(int argc, const char **argv, const char *prefix,\n+\t\t\tstruct repository *repo UNUSED)\n {\n \tint add_mode = 0;\n \tstruct option options[] = {\n@@ -1635,7 +1643,8 @@ static int set_branches(int argc, const char **argv, const char *prefix)\n \treturn set_remote_branches(argv[0], argv + 1, add_mode);\n }\n \n-static int get_url(int argc, const char **argv, const char *prefix)\n+static int get_url(int argc, const char **argv, const char *prefix,\n+\t\t   struct repository *repo UNUSED)\n {\n \tint i, push_mode = 0, all_mode = 0;\n \tconst char *remotename = NULL;\n@@ -1674,7 +1683,8 @@ static int get_url(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int set_url(int argc, const char **argv, const char *prefix)\n+static int set_url(int argc, const char **argv, const char *prefix,\n+\t\t   struct repository *repo UNUSED)\n {\n \tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n \tint matches = 0, negative_matches = 0;\n@@ -1765,7 +1775,7 @@ static int set_url(int argc, const char **argv, const char *prefix)\n int cmd_remote(int argc,\n \t       const char **argv,\n \t       const char *prefix,\n-\t       struct repository *repo UNUSED)\n+\t       struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option options[] = {\n@@ -1788,7 +1798,7 @@ int cmd_remote(int argc,\n \t\t\t     PARSE_OPT_SUBCOMMAND_OPTIONAL);\n \n \tif (fn) {\n-\t\treturn !!fn(argc, argv, prefix);\n+\t\treturn !!fn(argc, argv, prefix, repo);\n \t} else {\n \t\tif (argc) {\n \t\t\terror(_(\"unknown subcommand: `%s'\"), argv[0]);\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex 49aedc1de81a17b8b491cded7fa71b384e0e8be9..6f5fa5893b839fe21fef44ecbd837d132ebbac26 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -48,7 +48,8 @@ static char const * const builtin_sparse_checkout_list_usage[] = {\n \tNULL\n };\n \n-static int sparse_checkout_list(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n+\t\t\t\tstruct repository *repo UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_list_options[] = {\n \t\tOPT_END(),\n@@ -443,7 +444,8 @@ static struct sparse_checkout_init_opts {\n \tint sparse_index;\n } init_opts;\n \n-static int sparse_checkout_init(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n+\t\t\t\tstruct repository *repo UNUSED)\n {\n \tstruct pattern_list pl;\n \tchar *sparse_filename;\n@@ -770,7 +772,8 @@ static struct sparse_checkout_add_opts {\n \tint use_stdin;\n } add_opts;\n \n-static int sparse_checkout_add(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n+\t\t\t       struct repository *repo UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_add_options[] = {\n \t\tOPT_BOOL_F(0, \"skip-checks\", &add_opts.skip_checks,\n@@ -808,7 +811,8 @@ static struct sparse_checkout_set_opts {\n \tint use_stdin;\n } set_opts;\n \n-static int sparse_checkout_set(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n+\t\t\t       struct repository *repo UNUSED)\n {\n \tint default_patterns_nr = 2;\n \tconst char *default_patterns[] = {\"/*\", \"!/*/\", NULL};\n@@ -866,7 +870,8 @@ static struct sparse_checkout_reapply_opts {\n } reapply_opts;\n \n static int sparse_checkout_reapply(int argc, const char **argv,\n-\t\t\t\t   const char *prefix)\n+\t\t\t\t   const char *prefix,\n+\t\t\t\t   struct repository *repo UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_reapply_options[] = {\n \t\tOPT_BOOL(0, \"cone\", &reapply_opts.cone_mode,\n@@ -901,7 +906,8 @@ static char const * const builtin_sparse_checkout_disable_usage[] = {\n };\n \n static int sparse_checkout_disable(int argc, const char **argv,\n-\t\t\t\t   const char *prefix)\n+\t\t\t\t   const char *prefix,\n+\t\t\t\t   struct repository *repo UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_disable_options[] = {\n \t\tOPT_END(),\n@@ -989,7 +995,8 @@ static int check_rules(struct pattern_list *pl, int null_terminated) {\n \treturn 0;\n }\n \n-static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix,\n+\t\t\t\t       struct repository *repo UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_check_rules_options[] = {\n \t\tOPT_BOOL('z', NULL, &check_rules_opts.null_termination,\n@@ -1037,7 +1044,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *\n int cmd_sparse_checkout(int argc,\n \t\t\tconst char **argv,\n \t\t\tconst char *prefix,\n-\t\t\tstruct repository *repo UNUSED)\n+\t\t\tstruct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option builtin_sparse_checkout_options[] = {\n@@ -1060,5 +1067,5 @@ int cmd_sparse_checkout(int argc,\n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 1399a1bbe2c222ed3e1c33ac2dd17bd1148f709c..c212b1c0b2c7c55de2fdd5d7d7a247ce6f530960 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -249,7 +249,8 @@ static int do_clear_stash(void)\n \t\t\t       ref_stash, &obj, 0);\n }\n \n-static int clear_stash(int argc, const char **argv, const char *prefix)\n+static int clear_stash(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -652,7 +653,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,\n \treturn ret;\n }\n \n-static int apply_stash(int argc, const char **argv, const char *prefix)\n+static int apply_stash(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tint ret = -1;\n \tint quiet = 0;\n@@ -726,7 +728,8 @@ static int get_stash_info_assert(struct stash_info *info, int argc,\n \treturn 0;\n }\n \n-static int drop_stash(int argc, const char **argv, const char *prefix)\n+static int drop_stash(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tint ret = -1;\n \tint quiet = 0;\n@@ -748,7 +751,8 @@ static int drop_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int pop_stash(int argc, const char **argv, const char *prefix)\n+static int pop_stash(int argc, const char **argv, const char *prefix,\n+\t\t     struct repository *repo UNUSED)\n {\n \tint ret = -1;\n \tint index = 0;\n@@ -778,7 +782,8 @@ static int pop_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int branch_stash(int argc, const char **argv, const char *prefix)\n+static int branch_stash(int argc, const char **argv, const char *prefix,\n+\t\t\tstruct repository *repo UNUSED)\n {\n \tint ret = -1;\n \tconst char *branch = NULL;\n@@ -816,7 +821,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int list_stash(int argc, const char **argv, const char *prefix)\n+static int list_stash(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct option options[] = {\n@@ -889,7 +895,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op\n \tdo_diff_cache(&info->b_commit, diff_opt);\n }\n \n-static int show_stash(int argc, const char **argv, const char *prefix)\n+static int show_stash(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tint i;\n \tint ret = -1;\n@@ -1017,7 +1024,8 @@ static int do_store_stash(const struct object_id *w_commit, const char *stash_ms\n \treturn 0;\n }\n \n-static int store_stash(int argc, const char **argv, const char *prefix)\n+static int store_stash(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tint quiet = 0;\n \tconst char *stash_msg = NULL;\n@@ -1491,7 +1499,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b\n \treturn ret;\n }\n \n-static int create_stash(int argc, const char **argv, const char *prefix UNUSED)\n+static int create_stash(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\tstruct repository *repo UNUSED)\n {\n \tint ret;\n \tstruct strbuf stash_msg_buf = STRBUF_INIT;\n@@ -1827,12 +1836,14 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \treturn ret;\n }\n \n-static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n+static int push_stash_unassumed(int argc, const char **argv, const char *prefix,\n+\t\t\t\tstruct repository *repo UNUSED)\n {\n \treturn push_stash(argc, argv, prefix, 0);\n }\n \n-static int save_stash(int argc, const char **argv, const char *prefix)\n+static int save_stash(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tint keep_index = -1;\n \tint only_staged = 0;\n@@ -1878,7 +1889,7 @@ static int save_stash(int argc, const char **argv, const char *prefix)\n int cmd_stash(int argc,\n \t      const char **argv,\n \t      const char *prefix,\n-\t      struct repository *repo UNUSED)\n+\t      struct repository *repo)\n {\n \tpid_t pid = getpid();\n \tconst char *index_file;\n@@ -1916,9 +1927,9 @@ int cmd_stash(int argc,\n \t\t    (uintmax_t)pid);\n \n \tif (fn)\n-\t\treturn !!fn(argc, argv, prefix);\n+\t\treturn !!fn(argc, argv, prefix, repo);\n \telse if (!argc)\n-\t\treturn !!push_stash_unassumed(0, NULL, prefix);\n+\t\treturn !!push_stash_unassumed(0, NULL, prefix, repo);\n \n \t/* Assume 'stash push' */\n \tstrvec_push(&args, \"push\");\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b6b5f1ebde7c2e4780af4097a0c4d6d838948aee..19e587838132f26e2e10dc4a9f93f7b1c78cd49d 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -399,7 +399,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,\n \tfree(displaypath);\n }\n \n-static int module_foreach(int argc, const char **argv, const char *prefix)\n+static int module_foreach(int argc, const char **argv, const char *prefix,\n+\t\t\t  struct repository *repo UNUSED)\n {\n \tstruct foreach_cb info = FOREACH_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -544,7 +545,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data\n \t\t       info->flags);\n }\n \n-static int module_init(int argc, const char **argv, const char *prefix)\n+static int module_init(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tstruct init_cb info = INIT_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -738,7 +740,8 @@ static void status_submodule_cb(const struct cache_entry *list_item,\n \t\t\t info->prefix, info->super_prefix, info->flags);\n }\n \n-static int module_status(int argc, const char **argv, const char *prefix)\n+static int module_status(int argc, const char **argv, const char *prefix,\n+\t\t\t struct repository *repo UNUSED)\n {\n \tstruct status_cb info = STATUS_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1163,7 +1166,8 @@ static int compute_summary_module_list(struct object_id *head_oid,\n \treturn ret;\n }\n \n-static int module_summary(int argc, const char **argv, const char *prefix)\n+static int module_summary(int argc, const char **argv, const char *prefix,\n+\t\t\t  struct repository *repo UNUSED)\n {\n \tstruct summary_cb info = SUMMARY_CB_INIT;\n \tint cached = 0;\n@@ -1339,7 +1343,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data\n \t\t       info->flags);\n }\n \n-static int module_sync(int argc, const char **argv, const char *prefix)\n+static int module_sync(int argc, const char **argv, const char *prefix,\n+\t\t       struct repository *repo UNUSED)\n {\n \tstruct sync_cb info = SYNC_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1485,7 +1490,8 @@ static void deinit_submodule_cb(const struct cache_entry *list_item,\n \tdeinit_submodule(list_item->name, info->prefix, info->flags);\n }\n \n-static int module_deinit(int argc, const char **argv, const char *prefix)\n+static int module_deinit(int argc, const char **argv, const char *prefix,\n+\t\t\t struct repository *repo UNUSED)\n {\n \tstruct deinit_cb info = DEINIT_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1842,7 +1848,8 @@ static int clone_submodule(const struct module_clone_data *clone_data,\n \treturn 0;\n }\n \n-static int module_clone(int argc, const char **argv, const char *prefix)\n+static int module_clone(int argc, const char **argv, const char *prefix,\n+\t\t\tstruct repository *repo UNUSED)\n {\n \tint dissociate = 0, quiet = 0, progress = 0, require_init = 0;\n \tstruct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;\n@@ -2779,7 +2786,8 @@ static int update_submodules(struct update_data *update_data)\n \treturn ret;\n }\n \n-static int module_update(int argc, const char **argv, const char *prefix)\n+static int module_update(int argc, const char **argv, const char *prefix,\n+\t\t\t struct repository *repo UNUSED)\n {\n \tstruct pathspec pathspec = { 0 };\n \tstruct pathspec pathspec2 = { 0 };\n@@ -2911,7 +2919,8 @@ static int module_update(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int push_check(int argc, const char **argv, const char *prefix UNUSED)\n+static int push_check(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      struct repository *repo UNUSED)\n {\n \tstruct remote *remote;\n \tconst char *superproject_head;\n@@ -2991,7 +3000,8 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED)\n \treturn 0;\n }\n \n-static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n+static int absorb_git_dirs(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tint i;\n \tstruct pathspec pathspec = { 0 };\n@@ -3024,7 +3034,8 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int module_set_url(int argc, const char **argv, const char *prefix)\n+static int module_set_url(int argc, const char **argv, const char *prefix,\n+\t\t\t  struct repository *repo UNUSED)\n {\n \tint quiet = 0, ret;\n \tconst char *newurl;\n@@ -3063,7 +3074,8 @@ static int module_set_url(int argc, const char **argv, const char *prefix)\n \treturn !!ret;\n }\n \n-static int module_set_branch(int argc, const char **argv, const char *prefix)\n+static int module_set_branch(int argc, const char **argv, const char *prefix,\n+\t\t\t     struct repository *repo UNUSED)\n {\n \tint opt_default = 0, ret;\n \tconst char *opt_branch = NULL;\n@@ -3113,7 +3125,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)\n \treturn !!ret;\n }\n \n-static int module_create_branch(int argc, const char **argv, const char *prefix)\n+static int module_create_branch(int argc, const char **argv, const char *prefix,\n+\t\t\t\tstruct repository *repo UNUSED)\n {\n \tenum branch_track track;\n \tint quiet = 0, force = 0, reflog = 0, dry_run = 0;\n@@ -3424,7 +3437,8 @@ static void die_on_repo_without_commits(const char *path)\n \tstrbuf_release(&sb);\n }\n \n-static int module_add(int argc, const char **argv, const char *prefix)\n+static int module_add(int argc, const char **argv, const char *prefix,\n+\t\t      struct repository *repo UNUSED)\n {\n \tint force = 0, quiet = 0, progress = 0, dissociate = 0;\n \tstruct add_data add_data = ADD_DATA_INIT;\n@@ -3557,7 +3571,7 @@ static int module_add(int argc, const char **argv, const char *prefix)\n int cmd_submodule__helper(int argc,\n \t\t\t  const char **argv,\n \t\t\t  const char *prefix,\n-\t\t\t  struct repository *repo UNUSED)\n+\t\t\t  struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tconst char *const usage[] = {\n@@ -3583,5 +3597,5 @@ int cmd_submodule__helper(int argc,\n \t};\n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, repo);\n }\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex dae63dedf4cac2621f51f95a39aa456b33acd894..824dd71d643f112f384cde4de1373698c67de254 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -231,7 +231,8 @@ static void prune_worktrees(void)\n \tstrbuf_release(&reason);\n }\n \n-static int prune(int ac, const char **av, const char *prefix)\n+static int prune(int ac, const char **av, const char *prefix,\n+\t\t struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT__DRY_RUN(&show_only, N_(\"do not remove, show only\")),\n@@ -763,7 +764,8 @@ static char *dwim_branch(const char *path, char **new_branch)\n \treturn NULL;\n }\n \n-static int add(int ac, const char **av, const char *prefix)\n+static int add(int ac, const char **av, const char *prefix,\n+\t       struct repository *repo UNUSED)\n {\n \tstruct add_opts opts;\n \tconst char *new_branch_force = NULL;\n@@ -1039,7 +1041,8 @@ static void pathsort(struct worktree **wt)\n \tQSORT(wt, n, pathcmp);\n }\n \n-static int list(int ac, const char **av, const char *prefix)\n+static int list(int ac, const char **av, const char *prefix,\n+\t\tstruct repository *repo UNUSED)\n {\n \tint porcelain = 0;\n \tint line_terminator = '\\n';\n@@ -1084,7 +1087,8 @@ static int list(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n-static int lock_worktree(int ac, const char **av, const char *prefix)\n+static int lock_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t struct repository *repo UNUSED)\n {\n \tconst char *reason = \"\", *old_reason;\n \tstruct option options[] = {\n@@ -1119,7 +1123,8 @@ static int lock_worktree(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n-static int unlock_worktree(int ac, const char **av, const char *prefix)\n+static int unlock_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -1182,7 +1187,8 @@ static void validate_no_submodules(const struct worktree *wt)\n \t\tdie(_(\"working trees containing submodules cannot be moved or removed\"));\n }\n \n-static int move_worktree(int ac, const char **av, const char *prefix)\n+static int move_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t struct repository *repo UNUSED)\n {\n \tint force = 0;\n \tstruct option options[] = {\n@@ -1312,7 +1318,8 @@ static int delete_git_work_tree(struct worktree *wt)\n \treturn ret;\n }\n \n-static int remove_worktree(int ac, const char **av, const char *prefix)\n+static int remove_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n {\n \tint force = 0;\n \tstruct option options[] = {\n@@ -1377,7 +1384,8 @@ static void report_repair(int iserr, const char *path, const char *msg, void *cb\n \t}\n }\n \n-static int repair(int ac, const char **av, const char *prefix)\n+static int repair(int ac, const char **av, const char *prefix,\n+\t\t  struct repository *repo UNUSED)\n {\n \tconst char **p;\n \tconst char *self[] = { \".\", NULL };\n@@ -1397,7 +1405,7 @@ static int repair(int ac, const char **av, const char *prefix)\n int cmd_worktree(int ac,\n \t\t const char **av,\n \t\t const char *prefix,\n-\t\t struct repository *repo UNUSED)\n+\t\t struct repository *repo)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option options[] = {\n@@ -1422,5 +1430,5 @@ int cmd_worktree(int ac,\n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\n \n-\treturn fn(ac, av, prefix);\n+\treturn fn(ac, av, prefix, repo);\n }\ndiff --git a/parse-options.h b/parse-options.h\nindex ae15342390837c21503ab812648a7d8fd21432a8..f0801d4532a175b65783689f2a68fb56da2c8e87 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -3,6 +3,8 @@\n \n #include \"gettext.h\"\n \n+struct repository;\n+\n /**\n  * Refer to Documentation/technical/api-parse-options.txt for the API doc.\n  */\n@@ -73,7 +75,7 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,\n \t\t\t\t\t      const char *arg, int unset);\n \n typedef int parse_opt_subcommand_fn(int argc, const char **argv,\n-\t\t\t\t    const char *prefix);\n+\t\t\t\t    const char *prefix, struct repository *repo);\n \n /*\n  * `type`::\ndiff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c\nindex 5250913d99eba18a28878d3904cb7b2399670d02..5da359486cdcb353b277653111bc201c5f82851e 100644\n--- a/t/helper/test-parse-options.c\n+++ b/t/helper/test-parse-options.c\n@@ -282,14 +282,16 @@ int cmd__parse_options_flags(int argc, const char **argv)\n \treturn parse_options_flags__cmd(argc, argv, test_flags);\n }\n \n-static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED)\n+static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      struct repository *repo UNUSED)\n {\n \tprintf(\"fn: subcmd_one\\n\");\n \tprint_args(argc, argv);\n \treturn 0;\n }\n \n-static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED)\n+static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      struct repository *repo UNUSED)\n {\n \tprintf(\"fn: subcmd_two\\n\");\n \tprint_args(argc, argv);\n@@ -319,7 +321,7 @@ static int parse_subcommand__cmd(int argc, const char **argv,\n \n \tprintf(\"opt: %d\\n\", opt);\n \n-\treturn fn(argc, argv, NULL);\n+\treturn fn(argc, argv, NULL, NULL);\n }\n \n int cmd__parse_subcommand(int argc, const char **argv)\n\n---\n\n\n\n--- \n\nbase-commit: 04eaff62f286226f501dd21f069e0e257aee11a6\nchange-id: 20241122-374-add-repository-to-subsubcommands-226a391d95c7\n\nThanks\n- Karthik\n\n"},{"id":"508164","messageId":"CAP8UFD0=OycMAaDi_92-Go2Mt4q-s7cfmBaZD_kWBnZsvYpiPA@mail.gmail.com","threadId":"62542","inReplyTo":"20241125-374-add-repository-to-subsubcommands-v1-1-637a5e22ba48@gmail.com","subject":"Re: [PATCH] builtin: pass repository to sub commands","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2024-11-26T08:46:38Z","receivedAt":"2024-11-26T08:46:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, Nov 25, 2024 at 3:56 PM Karthik Nayak <karthik.188@gmail.com> wrote:\n>\n> In 9b1cb5070f (builtin: add a repository parameter for builtin\n> functions, 2024-09-13) the repository was passed down to all builtin\n> commands. This allowed the repository to be passed down to lower layers\n> without depending on the global `the_repository` variable.\n>\n> Continue this work by also passing down the repository parameter from\n> the command to sub-commands. This will help pass down the repository to\n> other subsystems and cleanup usage of global variables like\n> 'the_repository' and 'the_hash_algo'.\n>\n> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>\n\nYeah, this is definitely needed to cleanup usage of global variables,\nand looks well done to me. Ack.\n\nThanks.\n"},{"id":"508165","messageId":"Z0WNKV5prRE2Hupw@pks.im","threadId":"62542","inReplyTo":"20241125-374-add-repository-to-subsubcommands-v1-1-637a5e22ba48@gmail.com","subject":"Re: [PATCH] builtin: pass repository to sub commands","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-11-26T08:56:09Z","receivedAt":"2024-11-26T08:56:26Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Nov 25, 2024 at 03:55:30PM +0100, Karthik Nayak wrote:\n> In 9b1cb5070f (builtin: add a repository parameter for builtin\n> functions, 2024-09-13) the repository was passed down to all builtin\n> commands. This allowed the repository to be passed down to lower layers\n> without depending on the global `the_repository` variable.\n> \n> Continue this work by also passing down the repository parameter from\n> the command to sub-commands. This will help pass down the repository to\n> other subsystems and cleanup usage of global variables like\n> 'the_repository' and 'the_hash_algo'.\n\nOne alternative could be to instead pass a caller-provided structure to\nthe subcommands. Right now that isn't really needed because we tend to\nmake use of not only `the_repository` as a global variable, but also\nbecause we track all kinds of other variables globally.\n\nSo if the code were refactored to instead accept an arbitrary `void *`\npointer, callers could provide a custom structure and pass that along to\nits subcommands. In many cases we may end up just passing the repo\ndirectly, but I'm sure there are others where this direction would buy\nus additional flexibility and allow us to get rid of even more global\nstate.\n\nPatrick\n"},{"id":"508167","messageId":"CAOLa=ZSF6PC0dXGE8JUeeZqQgxgGAMnKJNGNeEMTwhCwN-OXYQ@mail.gmail.com","threadId":"62542","inReplyTo":"CAP8UFD0=OycMAaDi_92-Go2Mt4q-s7cfmBaZD_kWBnZsvYpiPA@mail.gmail.com","subject":"Re: [PATCH] builtin: pass repository to sub commands","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-26T09:50:10Z","receivedAt":"2024-11-26T09:50:11Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> On Mon, Nov 25, 2024 at 3:56 PM Karthik Nayak <karthik.188@gmail.com> wrote:\n>>\n>> In 9b1cb5070f (builtin: add a repository parameter for builtin\n>> functions, 2024-09-13) the repository was passed down to all builtin\n>> commands. This allowed the repository to be passed down to lower layers\n>> without depending on the global `the_repository` variable.\n>>\n>> Continue this work by also passing down the repository parameter from\n>> the command to sub-commands. This will help pass down the repository to\n>> other subsystems and cleanup usage of global variables like\n>> 'the_repository' and 'the_hash_algo'.\n>>\n>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>\n>\n> Yeah, this is definitely needed to cleanup usage of global variables,\n> and looks well done to me. Ack.\n>\n\nThanks for the review.\n"},{"id":"508168","messageId":"CAOLa=ZTUv41jfPcevaY+Afxu2e03_C9bDF+uXzNha-24LH+Lmw@mail.gmail.com","threadId":"62542","inReplyTo":"Z0WNKV5prRE2Hupw@pks.im","subject":"Re: [PATCH] builtin: pass repository to sub commands","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-26T09:56:10Z","receivedAt":"2024-11-26T09:56:12Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Mon, Nov 25, 2024 at 03:55:30PM +0100, Karthik Nayak wrote:\n>> In 9b1cb5070f (builtin: add a repository parameter for builtin\n>> functions, 2024-09-13) the repository was passed down to all builtin\n>> commands. This allowed the repository to be passed down to lower layers\n>> without depending on the global `the_repository` variable.\n>>\n>> Continue this work by also passing down the repository parameter from\n>> the command to sub-commands. This will help pass down the repository to\n>> other subsystems and cleanup usage of global variables like\n>> 'the_repository' and 'the_hash_algo'.\n>\n> One alternative could be to instead pass a caller-provided structure to\n> the subcommands. Right now that isn't really needed because we tend to\n> make use of not only `the_repository` as a global variable, but also\n> because we track all kinds of other variables globally.\n>\n> So if the code were refactored to instead accept an arbitrary `void *`\n> pointer, callers could provide a custom structure and pass that along to\n> its subcommands. In many cases we may end up just passing the repo\n> directly, but I'm sure there are others where this direction would buy\n> us additional flexibility and allow us to get rid of even more global\n> state.\n>\n\nThat's a really good idea. I do see the merit of doing that, I'm not\nsure if such a need would actually arise. But then, the fallback would\nstill be `repository *` so I think it should work indeed. Will modify and\nsend. Thanks.\n"},{"id":"508181","messageId":"20241126-374-add-repository-to-subsubcommands-v2-1-417e0dc66c75@gmail.com","threadId":"62542","inReplyTo":"20241125-374-add-repository-to-subsubcommands-v1-1-637a5e22ba48@gmail.com","subject":"[PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-26T11:19:22Z","receivedAt":"2024-11-26T11:19:43Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"In 9b1cb5070f (builtin: add a repository parameter for builtin\nfunctions, 2024-09-13) the repository was passed down to all builtin\ncommands. This allowed the repository to be passed down to lower layers\nwithout depending on the global `the_repository` variable.\n\nTo remove usage of global variables like `the_repository` in\nsub-commands, it makes sense to pass down the repository value from the\ncommands to the sub-commands. But let's make it more generic and modify\n`parse_opt_subcommand_fn` to instead take a `void *` value. This way we\ncan provide custom structures to each sub-command.\n\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\nThis patch was part of my series to clean up the midx.c and midx-write.c\nfiles from using global variables [1]. Since this patch stands on its own,\nI've split it from the series. This should help merging this quicker\nsince it affects a lot more files but is isolated to one patch. \n\nI will re-send a new version of the series to depend on this patch. \n\nThis patch conflicts with 'gitster/bf/set-head-symref' on seen. But it is \nnot a dependency and the resolution should be simple enough. Happy to\nresend after merging that in if needed. \n\n[1]: https://lore.kernel.org/all/20241115-374-refactor-midx-c-and-midx-write-c-to-not-depend-on-global-state-v1-0-761f8a2c7775@gmail.com/\n---\nChanges in v2:\n- Change from sending `repository *` to `void *`. This makes it more generic\n  and allows us to send custom structures to sub-commands. Thanks Patrick. \n- Link to v1: https://lore.kernel.org/r/20241125-374-add-repository-to-subsubcommands-v1-1-637a5e22ba48@gmail.com\n---\n builtin/bisect.c              | 29 ++++++++++++++++++----------\n builtin/bundle.c              | 14 +++++++++-----\n builtin/commit-graph.c        |  8 +++++---\n builtin/config.c              | 23 ++++++++++++++--------\n builtin/gc.c                  | 19 ++++++++++++-------\n builtin/hook.c                |  5 +++--\n builtin/multi-pack-index.c    | 10 +++++-----\n builtin/notes.c               | 34 +++++++++++++++++++++------------\n builtin/reflog.c              | 21 +++++++++++++--------\n builtin/refs.c                |  8 +++++---\n builtin/remote.c              | 32 ++++++++++++++++++++-----------\n builtin/sparse-checkout.c     | 21 +++++++++++++--------\n builtin/stash.c               | 37 +++++++++++++++++++++++-------------\n builtin/submodule--helper.c   | 44 ++++++++++++++++++++++++++++---------------\n builtin/worktree.c            | 26 ++++++++++++++++---------\n parse-options.h               |  2 +-\n t/helper/test-parse-options.c |  8 +++++---\n 17 files changed, 218 insertions(+), 123 deletions(-)\n\ndiff --git a/builtin/bisect.c b/builtin/bisect.c\nindex 21d17a6c1a83e51fb82b53703b95d89bd9028830..dde7a8c6590b1b56ac123fcfd15c1e900ae0fdce 100644\n--- a/builtin/bisect.c\n+++ b/builtin/bisect.c\n@@ -1312,7 +1312,8 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \treturn res;\n }\n \n-static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     void *data UNUSED)\n {\n \tif (argc > 1)\n \t\treturn error(_(\"'%s' requires either no argument or a commit\"),\n@@ -1320,7 +1321,8 @@ static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNU\n \treturn bisect_reset(argc ? argv[0] : NULL);\n }\n \n-static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1333,7 +1335,8 @@ static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNU\n \treturn res;\n }\n \n-static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t     void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1344,7 +1347,8 @@ static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNU\n \treturn res;\n }\n \n-static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)\n+static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix,\n+\t\t\t    void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1358,12 +1362,14 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref\n \treturn res;\n }\n \n-static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, const char *prefix UNUSED)\n+static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED,\n+\t\t\t   const char *prefix UNUSED, void *data UNUSED)\n {\n \treturn bisect_log();\n }\n \n-static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t      void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1376,7 +1382,8 @@ static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UN\n \treturn res;\n }\n \n-static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t    void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1388,7 +1395,8 @@ static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUS\n \treturn res;\n }\n \n-static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t\t void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1399,7 +1407,8 @@ static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix\n \treturn res;\n }\n \n-static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)\n+static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\t   void *data UNUSED)\n {\n \tint res;\n \tstruct bisect_terms terms = { 0 };\n@@ -1451,7 +1460,7 @@ int cmd_bisect(int argc,\n \t} else {\n \t\targc--;\n \t\targv++;\n-\t\tres = fn(argc, argv, prefix);\n+\t\tres = fn(argc, argv, prefix, NULL);\n \t}\n \n \treturn is_bisect_success(res) ? 0 : -res;\ndiff --git a/builtin/bundle.c b/builtin/bundle.c\nindex 127518c2a8d3c4ec0bde62f1932e964ce9bcf66f..dfb8d16300c96994b8d0add62174b498384aa367 100644\n--- a/builtin/bundle.c\n+++ b/builtin/bundle.c\n@@ -67,7 +67,8 @@ static int parse_options_cmd_bundle(int argc,\n \treturn argc;\n }\n \n-static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_create(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED) {\n \tstruct strvec pack_opts = STRVEC_INIT;\n \tint version = -1;\n \tint ret;\n@@ -123,7 +124,8 @@ static int open_bundle(const char *path, struct bundle_header *header,\n \treturn read_bundle_header(path, header);\n }\n \n-static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_verify(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint quiet = 0;\n@@ -164,7 +166,8 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {\n \treturn ret;\n }\n \n-static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix,\n+\t\t\t\t void *data UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint ret;\n@@ -189,7 +192,8 @@ static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix\n \treturn ret;\n }\n \n-static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {\n+static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix,\n+\t\t\t       void *data UNUSED) {\n \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n \tint bundle_fd = -1;\n \tint ret;\n@@ -247,5 +251,5 @@ int cmd_bundle(int argc,\n \n \tpacket_trace_identity(\"bundle\");\n \n-\treturn !!fn(argc, argv, prefix);\n+\treturn !!fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/commit-graph.c b/builtin/commit-graph.c\nindex 7c991db6eb48ad6e935727a079abac02bb358f8a..8eeef506f5ca75b337e59fe2b0fc82bd76948710 100644\n--- a/builtin/commit-graph.c\n+++ b/builtin/commit-graph.c\n@@ -62,7 +62,8 @@ static struct option *add_common_options(struct option *to)\n \treturn parse_options_concat(common_opts, to);\n }\n \n-static int graph_verify(int argc, const char **argv, const char *prefix)\n+static int graph_verify(int argc, const char **argv, const char *prefix,\n+\t\t\tvoid *data UNUSED)\n {\n \tstruct commit_graph *graph = NULL;\n \tstruct object_directory *odb = NULL;\n@@ -214,7 +215,8 @@ static int git_commit_graph_write_config(const char *var, const char *value,\n \treturn 0;\n }\n \n-static int graph_write(int argc, const char **argv, const char *prefix)\n+static int graph_write(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tstruct string_list pack_indexes = STRING_LIST_INIT_DUP;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -352,5 +354,5 @@ int cmd_commit_graph(int argc,\n \t\t\t     builtin_commit_graph_usage, 0);\n \tFREE_AND_NULL(options);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/config.c b/builtin/config.c\nindex cba702210815b716a5c6c93ebb69d8c485901e43..304ba147a2cbb1c63ef838aeaa67c5d5b8e2ef27 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -826,7 +826,8 @@ static void display_options_init(struct config_display_options *opts)\n \t}\n }\n \n-static int cmd_config_list(int argc, const char **argv, const char *prefix)\n+static int cmd_config_list(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n@@ -861,7 +862,8 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int cmd_config_get(int argc, const char **argv, const char *prefix)\n+static int cmd_config_get(int argc, const char **argv, const char *prefix,\n+\t\t\t  void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n@@ -915,7 +917,8 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_set(int argc, const char **argv, const char *prefix)\n+static int cmd_config_set(int argc, const char **argv, const char *prefix,\n+\t\t\t  void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tconst char *value_pattern = NULL, *comment_arg = NULL;\n@@ -973,7 +976,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_unset(int argc, const char **argv, const char *prefix)\n+static int cmd_config_unset(int argc, const char **argv, const char *prefix,\n+\t\t\t    void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tconst char *value_pattern = NULL;\n@@ -1010,7 +1014,8 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)\n+static int cmd_config_rename_section(int argc, const char **argv, const char *prefix,\n+\t\t\t\t     void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1039,7 +1044,8 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr\n \treturn ret;\n }\n \n-static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)\n+static int cmd_config_remove_section(int argc, const char **argv, const char *prefix,\n+\t\t\t\t     void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1099,7 +1105,8 @@ static int show_editor(struct config_location_options *opts)\n \treturn 0;\n }\n \n-static int cmd_config_edit(int argc, const char **argv, const char *prefix)\n+static int cmd_config_edit(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n \tstruct option opts[] = {\n@@ -1422,7 +1429,7 @@ int cmd_config(int argc,\n \tif (subcommand) {\n \t\targc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage,\n \t\t       PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT);\n-\t\treturn subcommand(argc, argv, prefix);\n+\t\treturn subcommand(argc, argv, prefix, NULL);\n \t}\n \n \treturn cmd_config_actions(argc, argv, prefix);\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex d52735354c9f87ba4e8acb593dd11aa0482223e1..94f357c64680b275a7512505b18ecae76d03b5c9 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -1561,7 +1561,8 @@ static int task_option_parse(const struct option *opt UNUSED,\n \treturn 0;\n }\n \n-static int maintenance_run(int argc, const char **argv, const char *prefix)\n+static int maintenance_run(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tint i;\n \tstruct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;\n@@ -1623,7 +1624,8 @@ static char const * const builtin_maintenance_register_usage[] = {\n \tNULL\n };\n \n-static int maintenance_register(int argc, const char **argv, const char *prefix)\n+static int maintenance_register(int argc, const char **argv, const char *prefix,\n+\t\t\t\tvoid *data UNUSED)\n {\n \tchar *config_file = NULL;\n \tstruct option options[] = {\n@@ -1687,7 +1689,8 @@ static char const * const builtin_maintenance_unregister_usage[] = {\n \tNULL\n };\n \n-static int maintenance_unregister(int argc, const char **argv, const char *prefix)\n+static int maintenance_unregister(int argc, const char **argv, const char *prefix,\n+\t\t\t\t  void *data UNUSED)\n {\n \tint force = 0;\n \tchar *config_file = NULL;\n@@ -2917,7 +2920,8 @@ static const char *const builtin_maintenance_start_usage[] = {\n \tNULL\n };\n \n-static int maintenance_start(int argc, const char **argv, const char *prefix)\n+static int maintenance_start(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED)\n {\n \tstruct maintenance_start_opts opts = { 0 };\n \tstruct option options[] = {\n@@ -2940,7 +2944,7 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)\n \tif (update_background_schedule(&opts, 1))\n \t\tdie(_(\"failed to set up maintenance schedule\"));\n \n-\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))\n+\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, the_repository))\n \t\twarning(_(\"failed to add repo to global config\"));\n \treturn 0;\n }\n@@ -2950,7 +2954,8 @@ static const char *const builtin_maintenance_stop_usage[] = {\n \tNULL\n };\n \n-static int maintenance_stop(int argc, const char **argv, const char *prefix)\n+static int maintenance_stop(int argc, const char **argv, const char *prefix,\n+\t\t\t    void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -2984,5 +2989,5 @@ int cmd_maintenance(int argc,\n \n \targc = parse_options(argc, argv, prefix, builtin_maintenance_options,\n \t\t\t     builtin_maintenance_usage, 0);\n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/hook.c b/builtin/hook.c\nindex 367ef3e0b893fa16756880395151a82ed053acd8..973a3b08387b6414a832f946d0437cbc9ca6c353 100644\n--- a/builtin/hook.c\n+++ b/builtin/hook.c\n@@ -19,7 +19,8 @@ static const char * const builtin_hook_run_usage[] = {\n \tNULL\n };\n \n-static int run(int argc, const char **argv, const char *prefix)\n+static int run(int argc, const char **argv, const char *prefix,\n+\t       void *data UNUSED)\n {\n \tint i;\n \tstruct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;\n@@ -81,5 +82,5 @@ int cmd_hook(int argc,\n \targc = parse_options(argc, argv, NULL, builtin_hook_options,\n \t\t\t     builtin_hook_usage, 0);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c\nindex d159ed1314d912a390ed725659b3abe7c821b83f..aef59f4758534aa60a363a9cdbc412e90ffa6f40 100644\n--- a/builtin/multi-pack-index.c\n+++ b/builtin/multi-pack-index.c\n@@ -119,7 +119,7 @@ static void read_packs_from_stdin(struct string_list *to)\n }\n \n static int cmd_multi_pack_index_write(int argc, const char **argv,\n-\t\t\t\t      const char *prefix)\n+\t\t\t\t      const char *prefix, void *data UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_write_options[] = {\n@@ -183,7 +183,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_verify(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix, void *data UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_verify_options[] = {\n@@ -210,7 +210,7 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_expire(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix, void *data UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_expire_options[] = {\n@@ -237,7 +237,7 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,\n }\n \n static int cmd_multi_pack_index_repack(int argc, const char **argv,\n-\t\t\t\t       const char *prefix)\n+\t\t\t\t       const char *prefix, void *data UNUSED)\n {\n \tstruct option *options;\n \tstatic struct option builtin_multi_pack_index_repack_options[] = {\n@@ -297,7 +297,7 @@ int cmd_multi_pack_index(int argc,\n \t\t\t     builtin_multi_pack_index_usage, 0);\n \tFREE_AND_NULL(options);\n \n-\tres = fn(argc, argv, prefix);\n+\tres = fn(argc, argv, prefix, NULL);\n \n \tfree(opts.object_dir);\n \treturn res;\ndiff --git a/builtin/notes.c b/builtin/notes.c\nindex 72c8a51cfacf72e1f115774487311b3d4464d204..b134c3ab6ccd4e7da33f85cf2b38eb328353f185 100644\n--- a/builtin/notes.c\n+++ b/builtin/notes.c\n@@ -431,7 +431,8 @@ static struct notes_tree *init_notes_check(const char *subcommand,\n \treturn t;\n }\n \n-static int list(int argc, const char **argv, const char *prefix)\n+static int list(int argc, const char **argv, const char *prefix,\n+\t\tvoid *data UNUSED)\n {\n \tstruct notes_tree *t;\n \tstruct object_id object;\n@@ -468,9 +469,11 @@ static int list(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int append_edit(int argc, const char **argv, const char *prefix);\n+static int append_edit(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED);\n \n-static int add(int argc, const char **argv, const char *prefix)\n+static int add(int argc, const char **argv, const char *prefix,\n+\t       void *data UNUSED)\n {\n \tint force = 0, allow_empty = 0;\n \tconst char *object_ref;\n@@ -543,7 +546,7 @@ static int add(int argc, const char **argv, const char *prefix)\n \t\t\t * argv[0-1].\n \t\t\t */\n \t\t\targv[0] = \"edit\";\n-\t\t\treturn append_edit(argc, argv, prefix);\n+\t\t\treturn append_edit(argc, argv, prefix, NULL);\n \t\t}\n \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n \t\t\toid_to_hex(&object));\n@@ -569,7 +572,8 @@ static int add(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int copy(int argc, const char **argv, const char *prefix)\n+static int copy(int argc, const char **argv, const char *prefix,\n+\t\tvoid *data UNUSED)\n {\n \tint retval = 0, force = 0, from_stdin = 0;\n \tconst struct object_id *from_note, *note;\n@@ -646,7 +650,8 @@ static int copy(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int append_edit(int argc, const char **argv, const char *prefix)\n+static int append_edit(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tint allow_empty = 0;\n \tconst char *object_ref;\n@@ -749,7 +754,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int show(int argc, const char **argv, const char *prefix)\n+static int show(int argc, const char **argv, const char *prefix,\n+\t\tvoid *data UNUSED)\n {\n \tconst char *object_ref;\n \tstruct notes_tree *t;\n@@ -875,7 +881,8 @@ static int git_config_get_notes_strategy(const char *key,\n \treturn 0;\n }\n \n-static int merge(int argc, const char **argv, const char *prefix)\n+static int merge(int argc, const char **argv, const char *prefix,\n+\t\t void *data UNUSED)\n {\n \tstruct strbuf remote_ref = STRBUF_INIT, msg = STRBUF_INIT;\n \tstruct object_id result_oid;\n@@ -1016,7 +1023,8 @@ static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag\n \treturn (flag & IGNORE_MISSING) ? 0 : status;\n }\n \n-static int remove_cmd(int argc, const char **argv, const char *prefix)\n+static int remove_cmd(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tunsigned flag = 0;\n \tint from_stdin = 0;\n@@ -1059,7 +1067,8 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)\n \treturn retval;\n }\n \n-static int prune(int argc, const char **argv, const char *prefix)\n+static int prune(int argc, const char **argv, const char *prefix,\n+\t\t void *data UNUSED)\n {\n \tstruct notes_tree *t;\n \tint show_only = 0, verbose = 0;\n@@ -1088,7 +1097,8 @@ static int prune(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int get_ref(int argc, const char **argv, const char *prefix)\n+static int get_ref(int argc, const char **argv, const char *prefix,\n+\t\t   void *data UNUSED)\n {\n \tstruct option options[] = { OPT_END() };\n \tchar *notes_ref;\n@@ -1148,5 +1158,5 @@ int cmd_notes(int argc,\n \t\tstrbuf_release(&sb);\n \t}\n \n-\treturn !!fn(argc, argv, prefix);\n+\treturn !!fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/reflog.c b/builtin/reflog.c\nindex 22df6834f71098ab8378e4423967f0fb87858340..65a0de6229eebf2e22e7db7eb0d611964a4dfada 100644\n--- a/builtin/reflog.c\n+++ b/builtin/reflog.c\n@@ -234,7 +234,8 @@ static int expire_total_callback(const struct option *opt,\n \treturn 0;\n }\n \n-static int cmd_reflog_show(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_show(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -253,7 +254,8 @@ static int show_reflog(const char *refname, void *cb_data UNUSED)\n \treturn 0;\n }\n \n-static int cmd_reflog_list(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_list(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -270,7 +272,8 @@ static int cmd_reflog_list(int argc, const char **argv, const char *prefix)\n \treturn refs_for_each_reflog(ref_store, show_reflog, NULL);\n }\n \n-static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED)\n {\n \tstruct cmd_reflog_expire_cb cmd = { 0 };\n \ttimestamp_t now = time(NULL);\n@@ -394,7 +397,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n \treturn status;\n }\n \n-static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_delete(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED)\n {\n \tint i, status = 0;\n \tunsigned int flags = 0;\n@@ -424,7 +428,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)\n \treturn status;\n }\n \n-static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)\n+static int cmd_reflog_exists(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -450,7 +455,7 @@ static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)\n int cmd_reflog(int argc,\n \t       const char **argv,\n \t       const char *prefix,\n-\t       struct repository *repository)\n+\t       struct repository *repository UNUSED)\n {\n \tparse_opt_subcommand_fn *fn = NULL;\n \tstruct option options[] = {\n@@ -467,7 +472,7 @@ int cmd_reflog(int argc,\n \t\t\t     PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |\n \t\t\t     PARSE_OPT_KEEP_UNKNOWN_OPT);\n \tif (fn)\n-\t\treturn fn(argc - 1, argv + 1, prefix);\n+\t\treturn fn(argc - 1, argv + 1, prefix, NULL);\n \telse\n-\t\treturn cmd_log_reflog(argc, argv, prefix, repository);\n+\t\treturn cmd_log_reflog(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/refs.c b/builtin/refs.c\nindex 24978a7b7b081ac6ed8ca99016f201d34c0639f8..3af697b957e2e67eb58f274f0d08e3dc0ca9276e 100644\n--- a/builtin/refs.c\n+++ b/builtin/refs.c\n@@ -12,7 +12,8 @@\n #define REFS_VERIFY_USAGE \\\n \tN_(\"git refs verify [--strict] [--verbose]\")\n \n-static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)\n+static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n+\t\t\t    void *data UNUSED)\n {\n \tconst char * const migrate_usage[] = {\n \t\tREFS_MIGRATE_USAGE,\n@@ -63,7 +64,8 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)\n \treturn err;\n }\n \n-static int cmd_refs_verify(int argc, const char **argv, const char *prefix)\n+static int cmd_refs_verify(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;\n \tconst char * const verify_usage[] = {\n@@ -108,5 +110,5 @@ int cmd_refs(int argc,\n \t};\n \n \targc = parse_options(argc, argv, prefix, opts, refs_usage, 0);\n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 909360096513fc72445f54b13ee92d7a95111ce1..119b6b367b7d831efc2cf30ecbea73659de78ffa 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -155,7 +155,8 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)\n \treturn 0;\n }\n \n-static int add(int argc, const char **argv, const char *prefix)\n+static int add(int argc, const char **argv, const char *prefix,\n+\t       void *data UNUSED)\n {\n \tint fetch = 0, fetch_tags = TAGS_DEFAULT;\n \tunsigned mirror = MIRROR_NONE;\n@@ -706,7 +707,8 @@ static void handle_push_default(const char* old_name, const char* new_name)\n }\n \n \n-static int mv(int argc, const char **argv, const char *prefix)\n+static int mv(int argc, const char **argv, const char *prefix,\n+\t      void *data UNUSED)\n {\n \tint show_progress = isatty(2);\n \tstruct option options[] = {\n@@ -881,7 +883,8 @@ static int mv(int argc, const char **argv, const char *prefix)\n \treturn result;\n }\n \n-static int rm(int argc, const char **argv, const char *prefix)\n+static int rm(int argc, const char **argv, const char *prefix,\n+\t      void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -1303,7 +1306,8 @@ static int show_all(void)\n \treturn result;\n }\n \n-static int show(int argc, const char **argv, const char *prefix)\n+static int show(int argc, const char **argv, const char *prefix,\n+\t\tvoid *data UNUSED)\n {\n \tint no_query = 0, result = 0, query_flag = 0;\n \tstruct option options[] = {\n@@ -1399,7 +1403,8 @@ static int show(int argc, const char **argv, const char *prefix)\n \treturn result;\n }\n \n-static int set_head(int argc, const char **argv, const char *prefix)\n+static int set_head(int argc, const char **argv, const char *prefix,\n+\t\t    void *data UNUSED)\n {\n \tint i, opt_a = 0, opt_d = 0, result = 0;\n \tstruct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;\n@@ -1503,7 +1508,8 @@ static int prune_remote(const char *remote, int dry_run)\n \treturn result;\n }\n \n-static int prune(int argc, const char **argv, const char *prefix)\n+static int prune(int argc, const char **argv, const char *prefix,\n+\t\t void *data UNUSED)\n {\n \tint dry_run = 0, result = 0;\n \tstruct option options[] = {\n@@ -1534,7 +1540,8 @@ static int get_remote_default(const char *key, const char *value UNUSED,\n \treturn 0;\n }\n \n-static int update(int argc, const char **argv, const char *prefix)\n+static int update(int argc, const char **argv, const char *prefix,\n+\t\t  void *data UNUSED)\n {\n \tint i, prune = -1;\n \tstruct option options[] = {\n@@ -1616,7 +1623,8 @@ static int set_remote_branches(const char *remotename, const char **branches,\n \treturn 0;\n }\n \n-static int set_branches(int argc, const char **argv, const char *prefix)\n+static int set_branches(int argc, const char **argv, const char *prefix,\n+\t\t\tvoid *data UNUSED)\n {\n \tint add_mode = 0;\n \tstruct option options[] = {\n@@ -1635,7 +1643,8 @@ static int set_branches(int argc, const char **argv, const char *prefix)\n \treturn set_remote_branches(argv[0], argv + 1, add_mode);\n }\n \n-static int get_url(int argc, const char **argv, const char *prefix)\n+static int get_url(int argc, const char **argv, const char *prefix,\n+\t\t   void *data UNUSED)\n {\n \tint i, push_mode = 0, all_mode = 0;\n \tconst char *remotename = NULL;\n@@ -1674,7 +1683,8 @@ static int get_url(int argc, const char **argv, const char *prefix)\n \treturn 0;\n }\n \n-static int set_url(int argc, const char **argv, const char *prefix)\n+static int set_url(int argc, const char **argv, const char *prefix,\n+\t\t   void *data UNUSED)\n {\n \tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n \tint matches = 0, negative_matches = 0;\n@@ -1788,7 +1798,7 @@ int cmd_remote(int argc,\n \t\t\t     PARSE_OPT_SUBCOMMAND_OPTIONAL);\n \n \tif (fn) {\n-\t\treturn !!fn(argc, argv, prefix);\n+\t\treturn !!fn(argc, argv, prefix, NULL);\n \t} else {\n \t\tif (argc) {\n \t\t\terror(_(\"unknown subcommand: `%s'\"), argv[0]);\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex 49aedc1de81a17b8b491cded7fa71b384e0e8be9..c18133997476d6d8e90ef7a54a286b4889a3f905 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -48,7 +48,8 @@ static char const * const builtin_sparse_checkout_list_usage[] = {\n \tNULL\n };\n \n-static int sparse_checkout_list(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n+\t\t\t\tvoid *data UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_list_options[] = {\n \t\tOPT_END(),\n@@ -443,7 +444,8 @@ static struct sparse_checkout_init_opts {\n \tint sparse_index;\n } init_opts;\n \n-static int sparse_checkout_init(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n+\t\t\t\tvoid *data UNUSED)\n {\n \tstruct pattern_list pl;\n \tchar *sparse_filename;\n@@ -770,7 +772,8 @@ static struct sparse_checkout_add_opts {\n \tint use_stdin;\n } add_opts;\n \n-static int sparse_checkout_add(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n+\t\t\t       void *data UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_add_options[] = {\n \t\tOPT_BOOL_F(0, \"skip-checks\", &add_opts.skip_checks,\n@@ -808,7 +811,8 @@ static struct sparse_checkout_set_opts {\n \tint use_stdin;\n } set_opts;\n \n-static int sparse_checkout_set(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n+\t\t\t       void *data UNUSED)\n {\n \tint default_patterns_nr = 2;\n \tconst char *default_patterns[] = {\"/*\", \"!/*/\", NULL};\n@@ -866,7 +870,7 @@ static struct sparse_checkout_reapply_opts {\n } reapply_opts;\n \n static int sparse_checkout_reapply(int argc, const char **argv,\n-\t\t\t\t   const char *prefix)\n+\t\t\t\t   const char *prefix, void *data UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_reapply_options[] = {\n \t\tOPT_BOOL(0, \"cone\", &reapply_opts.cone_mode,\n@@ -901,7 +905,7 @@ static char const * const builtin_sparse_checkout_disable_usage[] = {\n };\n \n static int sparse_checkout_disable(int argc, const char **argv,\n-\t\t\t\t   const char *prefix)\n+\t\t\t\t   const char *prefix, void *data UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_disable_options[] = {\n \t\tOPT_END(),\n@@ -989,7 +993,8 @@ static int check_rules(struct pattern_list *pl, int null_terminated) {\n \treturn 0;\n }\n \n-static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)\n+static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix,\n+\t\t\t\t       void *data UNUSED)\n {\n \tstatic struct option builtin_sparse_checkout_check_rules_options[] = {\n \t\tOPT_BOOL('z', NULL, &check_rules_opts.null_termination,\n@@ -1060,5 +1065,5 @@ int cmd_sparse_checkout(int argc,\n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 1399a1bbe2c222ed3e1c33ac2dd17bd1148f709c..c0477240feb3f194240aafba8057636596326391 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -249,7 +249,8 @@ static int do_clear_stash(void)\n \t\t\t       ref_stash, &obj, 0);\n }\n \n-static int clear_stash(int argc, const char **argv, const char *prefix)\n+static int clear_stash(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -652,7 +653,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,\n \treturn ret;\n }\n \n-static int apply_stash(int argc, const char **argv, const char *prefix)\n+static int apply_stash(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tint ret = -1;\n \tint quiet = 0;\n@@ -726,7 +728,8 @@ static int get_stash_info_assert(struct stash_info *info, int argc,\n \treturn 0;\n }\n \n-static int drop_stash(int argc, const char **argv, const char *prefix)\n+static int drop_stash(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tint ret = -1;\n \tint quiet = 0;\n@@ -748,7 +751,8 @@ static int drop_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int pop_stash(int argc, const char **argv, const char *prefix)\n+static int pop_stash(int argc, const char **argv, const char *prefix,\n+\t\t     void *data UNUSED)\n {\n \tint ret = -1;\n \tint index = 0;\n@@ -778,7 +782,8 @@ static int pop_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int branch_stash(int argc, const char **argv, const char *prefix)\n+static int branch_stash(int argc, const char **argv, const char *prefix,\n+\t\t\tvoid *data UNUSED)\n {\n \tint ret = -1;\n \tconst char *branch = NULL;\n@@ -816,7 +821,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int list_stash(int argc, const char **argv, const char *prefix)\n+static int list_stash(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tstruct option options[] = {\n@@ -889,7 +895,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op\n \tdo_diff_cache(&info->b_commit, diff_opt);\n }\n \n-static int show_stash(int argc, const char **argv, const char *prefix)\n+static int show_stash(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tint i;\n \tint ret = -1;\n@@ -1017,7 +1024,8 @@ static int do_store_stash(const struct object_id *w_commit, const char *stash_ms\n \treturn 0;\n }\n \n-static int store_stash(int argc, const char **argv, const char *prefix)\n+static int store_stash(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tint quiet = 0;\n \tconst char *stash_msg = NULL;\n@@ -1491,7 +1499,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b\n \treturn ret;\n }\n \n-static int create_stash(int argc, const char **argv, const char *prefix UNUSED)\n+static int create_stash(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t\tvoid *data UNUSED)\n {\n \tint ret;\n \tstruct strbuf stash_msg_buf = STRBUF_INIT;\n@@ -1827,12 +1836,14 @@ static int push_stash(int argc, const char **argv, const char *prefix,\n \treturn ret;\n }\n \n-static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n+static int push_stash_unassumed(int argc, const char **argv, const char *prefix,\n+\t\t\t\tvoid *data UNUSED)\n {\n \treturn push_stash(argc, argv, prefix, 0);\n }\n \n-static int save_stash(int argc, const char **argv, const char *prefix)\n+static int save_stash(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tint keep_index = -1;\n \tint only_staged = 0;\n@@ -1916,9 +1927,9 @@ int cmd_stash(int argc,\n \t\t    (uintmax_t)pid);\n \n \tif (fn)\n-\t\treturn !!fn(argc, argv, prefix);\n+\t\treturn !!fn(argc, argv, prefix, NULL);\n \telse if (!argc)\n-\t\treturn !!push_stash_unassumed(0, NULL, prefix);\n+\t\treturn !!push_stash_unassumed(0, NULL, prefix, NULL);\n \n \t/* Assume 'stash push' */\n \tstrvec_push(&args, \"push\");\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b6b5f1ebde7c2e4780af4097a0c4d6d838948aee..6d69360ff236e98d2daa63a87750c270a14795a0 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -399,7 +399,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,\n \tfree(displaypath);\n }\n \n-static int module_foreach(int argc, const char **argv, const char *prefix)\n+static int module_foreach(int argc, const char **argv, const char *prefix,\n+\t\t\t  void *data UNUSED)\n {\n \tstruct foreach_cb info = FOREACH_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -544,7 +545,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data\n \t\t       info->flags);\n }\n \n-static int module_init(int argc, const char **argv, const char *prefix)\n+static int module_init(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tstruct init_cb info = INIT_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -738,7 +740,8 @@ static void status_submodule_cb(const struct cache_entry *list_item,\n \t\t\t info->prefix, info->super_prefix, info->flags);\n }\n \n-static int module_status(int argc, const char **argv, const char *prefix)\n+static int module_status(int argc, const char **argv, const char *prefix,\n+\t\t\t void *data UNUSED)\n {\n \tstruct status_cb info = STATUS_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1163,7 +1166,8 @@ static int compute_summary_module_list(struct object_id *head_oid,\n \treturn ret;\n }\n \n-static int module_summary(int argc, const char **argv, const char *prefix)\n+static int module_summary(int argc, const char **argv, const char *prefix,\n+\t\t\t  void *data UNUSED)\n {\n \tstruct summary_cb info = SUMMARY_CB_INIT;\n \tint cached = 0;\n@@ -1339,7 +1343,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data\n \t\t       info->flags);\n }\n \n-static int module_sync(int argc, const char **argv, const char *prefix)\n+static int module_sync(int argc, const char **argv, const char *prefix,\n+\t\t       void *data UNUSED)\n {\n \tstruct sync_cb info = SYNC_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1485,7 +1490,8 @@ static void deinit_submodule_cb(const struct cache_entry *list_item,\n \tdeinit_submodule(list_item->name, info->prefix, info->flags);\n }\n \n-static int module_deinit(int argc, const char **argv, const char *prefix)\n+static int module_deinit(int argc, const char **argv, const char *prefix,\n+\t\t\t void *data UNUSED)\n {\n \tstruct deinit_cb info = DEINIT_CB_INIT;\n \tstruct pathspec pathspec = { 0 };\n@@ -1842,7 +1848,8 @@ static int clone_submodule(const struct module_clone_data *clone_data,\n \treturn 0;\n }\n \n-static int module_clone(int argc, const char **argv, const char *prefix)\n+static int module_clone(int argc, const char **argv, const char *prefix,\n+\t\t\tvoid *data UNUSED)\n {\n \tint dissociate = 0, quiet = 0, progress = 0, require_init = 0;\n \tstruct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;\n@@ -2779,7 +2786,8 @@ static int update_submodules(struct update_data *update_data)\n \treturn ret;\n }\n \n-static int module_update(int argc, const char **argv, const char *prefix)\n+static int module_update(int argc, const char **argv, const char *prefix,\n+\t\t\t void *data UNUSED)\n {\n \tstruct pathspec pathspec = { 0 };\n \tstruct pathspec pathspec2 = { 0 };\n@@ -2911,7 +2919,8 @@ static int module_update(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int push_check(int argc, const char **argv, const char *prefix UNUSED)\n+static int push_check(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      void *data UNUSED)\n {\n \tstruct remote *remote;\n \tconst char *superproject_head;\n@@ -2991,7 +3000,8 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED)\n \treturn 0;\n }\n \n-static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n+static int absorb_git_dirs(int argc, const char **argv, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tint i;\n \tstruct pathspec pathspec = { 0 };\n@@ -3024,7 +3034,8 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n \treturn ret;\n }\n \n-static int module_set_url(int argc, const char **argv, const char *prefix)\n+static int module_set_url(int argc, const char **argv, const char *prefix,\n+\t\t\t  void *data UNUSED)\n {\n \tint quiet = 0, ret;\n \tconst char *newurl;\n@@ -3063,7 +3074,8 @@ static int module_set_url(int argc, const char **argv, const char *prefix)\n \treturn !!ret;\n }\n \n-static int module_set_branch(int argc, const char **argv, const char *prefix)\n+static int module_set_branch(int argc, const char **argv, const char *prefix,\n+\t\t\t     void *data UNUSED)\n {\n \tint opt_default = 0, ret;\n \tconst char *opt_branch = NULL;\n@@ -3113,7 +3125,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)\n \treturn !!ret;\n }\n \n-static int module_create_branch(int argc, const char **argv, const char *prefix)\n+static int module_create_branch(int argc, const char **argv, const char *prefix,\n+\t\t\t\tvoid *data UNUSED)\n {\n \tenum branch_track track;\n \tint quiet = 0, force = 0, reflog = 0, dry_run = 0;\n@@ -3424,7 +3437,8 @@ static void die_on_repo_without_commits(const char *path)\n \tstrbuf_release(&sb);\n }\n \n-static int module_add(int argc, const char **argv, const char *prefix)\n+static int module_add(int argc, const char **argv, const char *prefix,\n+\t\t      void *data UNUSED)\n {\n \tint force = 0, quiet = 0, progress = 0, dissociate = 0;\n \tstruct add_data add_data = ADD_DATA_INIT;\n@@ -3583,5 +3597,5 @@ int cmd_submodule__helper(int argc,\n \t};\n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \n-\treturn fn(argc, argv, prefix);\n+\treturn fn(argc, argv, prefix, NULL);\n }\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex dae63dedf4cac2621f51f95a39aa456b33acd894..972b584b2170e1fca1658e397b7776205f545822 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -231,7 +231,8 @@ static void prune_worktrees(void)\n \tstrbuf_release(&reason);\n }\n \n-static int prune(int ac, const char **av, const char *prefix)\n+static int prune(int ac, const char **av, const char *prefix,\n+\t\t void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT__DRY_RUN(&show_only, N_(\"do not remove, show only\")),\n@@ -763,7 +764,8 @@ static char *dwim_branch(const char *path, char **new_branch)\n \treturn NULL;\n }\n \n-static int add(int ac, const char **av, const char *prefix)\n+static int add(int ac, const char **av, const char *prefix,\n+\t       void *data UNUSED)\n {\n \tstruct add_opts opts;\n \tconst char *new_branch_force = NULL;\n@@ -1039,7 +1041,8 @@ static void pathsort(struct worktree **wt)\n \tQSORT(wt, n, pathcmp);\n }\n \n-static int list(int ac, const char **av, const char *prefix)\n+static int list(int ac, const char **av, const char *prefix,\n+\t\tvoid *data UNUSED)\n {\n \tint porcelain = 0;\n \tint line_terminator = '\\n';\n@@ -1084,7 +1087,8 @@ static int list(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n-static int lock_worktree(int ac, const char **av, const char *prefix)\n+static int lock_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t void *data UNUSED)\n {\n \tconst char *reason = \"\", *old_reason;\n \tstruct option options[] = {\n@@ -1119,7 +1123,8 @@ static int lock_worktree(int ac, const char **av, const char *prefix)\n \treturn 0;\n }\n \n-static int unlock_worktree(int ac, const char **av, const char *prefix)\n+static int unlock_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tstruct option options[] = {\n \t\tOPT_END()\n@@ -1182,7 +1187,8 @@ static void validate_no_submodules(const struct worktree *wt)\n \t\tdie(_(\"working trees containing submodules cannot be moved or removed\"));\n }\n \n-static int move_worktree(int ac, const char **av, const char *prefix)\n+static int move_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t void *data UNUSED)\n {\n \tint force = 0;\n \tstruct option options[] = {\n@@ -1312,7 +1318,8 @@ static int delete_git_work_tree(struct worktree *wt)\n \treturn ret;\n }\n \n-static int remove_worktree(int ac, const char **av, const char *prefix)\n+static int remove_worktree(int ac, const char **av, const char *prefix,\n+\t\t\t   void *data UNUSED)\n {\n \tint force = 0;\n \tstruct option options[] = {\n@@ -1377,7 +1384,8 @@ static void report_repair(int iserr, const char *path, const char *msg, void *cb\n \t}\n }\n \n-static int repair(int ac, const char **av, const char *prefix)\n+static int repair(int ac, const char **av, const char *prefix,\n+\t\t  void *data UNUSED)\n {\n \tconst char **p;\n \tconst char *self[] = { \".\", NULL };\n@@ -1422,5 +1430,5 @@ int cmd_worktree(int ac,\n \tprepare_repo_settings(the_repository);\n \tthe_repository->settings.command_requires_full_index = 0;\n \n-\treturn fn(ac, av, prefix);\n+\treturn fn(ac, av, prefix, NULL);\n }\ndiff --git a/parse-options.h b/parse-options.h\nindex ae15342390837c21503ab812648a7d8fd21432a8..18d4e0c412cc86942e2da1277804f8b233076bc4 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -73,7 +73,7 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,\n \t\t\t\t\t      const char *arg, int unset);\n \n typedef int parse_opt_subcommand_fn(int argc, const char **argv,\n-\t\t\t\t    const char *prefix);\n+\t\t\t\t    const char *prefix, void *data);\n \n /*\n  * `type`::\ndiff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c\nindex 5250913d99eba18a28878d3904cb7b2399670d02..86a4e596e347dc2b9c65205237486ab2d352f8c3 100644\n--- a/t/helper/test-parse-options.c\n+++ b/t/helper/test-parse-options.c\n@@ -282,14 +282,16 @@ int cmd__parse_options_flags(int argc, const char **argv)\n \treturn parse_options_flags__cmd(argc, argv, test_flags);\n }\n \n-static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED)\n+static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      void *data UNUSED)\n {\n \tprintf(\"fn: subcmd_one\\n\");\n \tprint_args(argc, argv);\n \treturn 0;\n }\n \n-static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED)\n+static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED,\n+\t\t      void *data UNUSED)\n {\n \tprintf(\"fn: subcmd_two\\n\");\n \tprint_args(argc, argv);\n@@ -319,7 +321,7 @@ static int parse_subcommand__cmd(int argc, const char **argv,\n \n \tprintf(\"opt: %d\\n\", opt);\n \n-\treturn fn(argc, argv, NULL);\n+\treturn fn(argc, argv, NULL, NULL);\n }\n \n int cmd__parse_subcommand(int argc, const char **argv)\n\n---\n\nRange-diff versus v1:\n\n1:  6bce012f61 ! 1:  0c5e6aba3f builtin: pass repository to sub commands\n    @@ Metadata\n     Author: Karthik Nayak <karthik.188@gmail.com>\n     \n      ## Commit message ##\n    -    builtin: pass repository to sub commands\n    +    builtin: allow passing custom data to sub-commands\n     \n         In 9b1cb5070f (builtin: add a repository parameter for builtin\n         functions, 2024-09-13) the repository was passed down to all builtin\n         commands. This allowed the repository to be passed down to lower layers\n         without depending on the global `the_repository` variable.\n     \n    -    Continue this work by also passing down the repository parameter from\n    -    the command to sub-commands. This will help pass down the repository to\n    -    other subsystems and cleanup usage of global variables like\n    -    'the_repository' and 'the_hash_algo'.\n    +    To remove usage of global variables like `the_repository` in\n    +    sub-commands, it makes sense to pass down the repository value from the\n    +    commands to the sub-commands. But let's make it more generic and modify\n    +    `parse_opt_subcommand_fn` to instead take a `void *` value. This way we\n    +    can provide custom structures to each sub-command.\n     \n         Signed-off-by: Karthik Nayak <karthik.188@gmail.com>\n     \n    @@ builtin/bisect.c: static int bisect_run(struct bisect_terms *terms, int argc, co\n      \n     -static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tif (argc > 1)\n      \t\treturn error(_(\"'%s' requires either no argument or a commit\"),\n    @@ builtin/bisect.c: static int cmd_bisect__reset(int argc, const char **argv, cons\n      \n     -static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__terms(int argc, const char **argv, cons\n      \n     -static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__start(int argc, const char **argv, cons\n      \n     -static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)\n     +static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix,\n    -+\t\t\t    struct repository *repo UNUSED)\n    ++\t\t\t    void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__next(int argc, const char **argv UNUSED\n      \n     -static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, const char *prefix UNUSED)\n     +static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED,\n    -+\t\t\t   const char *prefix UNUSED,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   const char *prefix UNUSED, void *data UNUSED)\n      {\n      \treturn bisect_log();\n      }\n      \n     -static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t      struct repository *repo UNUSED)\n    ++\t\t\t      void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__replay(int argc, const char **argv, con\n      \n     -static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t    struct repository *repo UNUSED)\n    ++\t\t\t    void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__skip(int argc, const char **argv, const\n      \n     -static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t\t void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    @@ builtin/bisect.c: static int cmd_bisect__visualize(int argc, const char **argv,\n      \n     -static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)\n     +static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tint res;\n      \tstruct bisect_terms terms = { 0 };\n    -@@ builtin/bisect.c: static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE\n    - int cmd_bisect(int argc,\n    - \t       const char **argv,\n    - \t       const char *prefix,\n    --\t       struct repository *repo UNUSED)\n    -+\t       struct repository *repo)\n    - {\n    - \tint res = 0;\n    - \tparse_opt_subcommand_fn *fn = NULL;\n     @@ builtin/bisect.c: int cmd_bisect(int argc,\n      \t} else {\n      \t\targc--;\n      \t\targv++;\n     -\t\tres = fn(argc, argv, prefix);\n    -+\t\tres = fn(argc, argv, prefix, repo);\n    ++\t\tres = fn(argc, argv, prefix, NULL);\n      \t}\n      \n      \treturn is_bisect_success(res) ? 0 : -res;\n    @@ builtin/bundle.c: static int parse_options_cmd_bundle(int argc,\n      \n     -static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {\n     +static int cmd_bundle_create(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED) {\n    ++\t\t\t     void *data UNUSED) {\n      \tstruct strvec pack_opts = STRVEC_INIT;\n      \tint version = -1;\n      \tint ret;\n    @@ builtin/bundle.c: static int open_bundle(const char *path, struct bundle_header\n      \n     -static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {\n     +static int cmd_bundle_verify(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED) {\n    ++\t\t\t     void *data UNUSED) {\n      \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n      \tint bundle_fd = -1;\n      \tint quiet = 0;\n    @@ builtin/bundle.c: static int cmd_bundle_verify(int argc, const char **argv, cons\n      \n     -static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {\n     +static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\t struct repository *repo UNUSED) {\n    ++\t\t\t\t void *data UNUSED) {\n      \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n      \tint bundle_fd = -1;\n      \tint ret;\n    @@ builtin/bundle.c: static int cmd_bundle_list_heads(int argc, const char **argv,\n      \n     -static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {\n     +static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix,\n    -+\t\t\t       struct repository *repo UNUSED) {\n    ++\t\t\t       void *data UNUSED) {\n      \tstruct bundle_header header = BUNDLE_HEADER_INIT;\n      \tint bundle_fd = -1;\n      \tint ret;\n    -@@ builtin/bundle.c: static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)\n    - int cmd_bundle(int argc,\n    - \t       const char **argv,\n    - \t       const char *prefix,\n    --\t       struct repository *repo UNUSED)\n    -+\t       struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option options[] = {\n     @@ builtin/bundle.c: int cmd_bundle(int argc,\n      \n      \tpacket_trace_identity(\"bundle\");\n      \n     -\treturn !!fn(argc, argv, prefix);\n    -+\treturn !!fn(argc, argv, prefix, repo);\n    ++\treturn !!fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/commit-graph.c ##\n    @@ builtin/commit-graph.c: static struct option *add_common_options(struct option *\n      \n     -static int graph_verify(int argc, const char **argv, const char *prefix)\n     +static int graph_verify(int argc, const char **argv, const char *prefix,\n    -+\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\tvoid *data UNUSED)\n      {\n      \tstruct commit_graph *graph = NULL;\n      \tstruct object_directory *odb = NULL;\n    @@ builtin/commit-graph.c: static int git_commit_graph_write_config(const char *var\n      \n     -static int graph_write(int argc, const char **argv, const char *prefix)\n     +static int graph_write(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tstruct string_list pack_indexes = STRING_LIST_INIT_DUP;\n      \tstruct strbuf buf = STRBUF_INIT;\n    -@@ builtin/commit-graph.c: static int graph_write(int argc, const char **argv, const char *prefix)\n    - int cmd_commit_graph(int argc,\n    - \t\t     const char **argv,\n    - \t\t     const char *prefix,\n    --\t\t     struct repository *repo UNUSED)\n    -+\t\t     struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option builtin_commit_graph_options[] = {\n     @@ builtin/commit-graph.c: int cmd_commit_graph(int argc,\n      \t\t\t     builtin_commit_graph_usage, 0);\n      \tFREE_AND_NULL(options);\n      \n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/config.c ##\n    @@ builtin/config.c: static void display_options_init(struct config_display_options\n      \n     -static int cmd_config_list(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_list(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n    @@ builtin/config.c: static int cmd_config_list(int argc, const char **argv, const\n      \n     -static int cmd_config_get(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_get(int argc, const char **argv, const char *prefix,\n    -+\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t  void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tstruct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;\n    @@ builtin/config.c: static int cmd_config_get(int argc, const char **argv, const c\n      \n     -static int cmd_config_set(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_set(int argc, const char **argv, const char *prefix,\n    -+\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t  void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tconst char *value_pattern = NULL, *comment_arg = NULL;\n    @@ builtin/config.c: static int cmd_config_set(int argc, const char **argv, const c\n      \n     -static int cmd_config_unset(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_unset(int argc, const char **argv, const char *prefix,\n    -+\t\t\t    struct repository *repo UNUSED)\n    ++\t\t\t    void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tconst char *value_pattern = NULL;\n    @@ builtin/config.c: static int cmd_config_unset(int argc, const char **argv, const\n      \n     -static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_rename_section(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t\t     void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tstruct option opts[] = {\n    @@ builtin/config.c: static int cmd_config_rename_section(int argc, const char **ar\n      \n     -static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_remove_section(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t\t     void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tstruct option opts[] = {\n    @@ builtin/config.c: static int show_editor(struct config_location_options *opts)\n      \n     -static int cmd_config_edit(int argc, const char **argv, const char *prefix)\n     +static int cmd_config_edit(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;\n      \tstruct option opts[] = {\n    -@@ builtin/config.c: static int cmd_config_actions(int argc, const char **argv, const char *prefix)\n    - int cmd_config(int argc,\n    - \t       const char **argv,\n    - \t       const char *prefix,\n    --\t       struct repository *repo UNUSED)\n    -+\t       struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *subcommand = NULL;\n    - \tstruct option subcommand_opts[] = {\n     @@ builtin/config.c: int cmd_config(int argc,\n      \tif (subcommand) {\n      \t\targc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage,\n      \t\t       PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT);\n     -\t\treturn subcommand(argc, argv, prefix);\n    -+\t\treturn subcommand(argc, argv, prefix, repo);\n    ++\t\treturn subcommand(argc, argv, prefix, NULL);\n      \t}\n      \n      \treturn cmd_config_actions(argc, argv, prefix);\n    @@ builtin/gc.c: static int task_option_parse(const struct option *opt UNUSED,\n      \n     -static int maintenance_run(int argc, const char **argv, const char *prefix)\n     +static int maintenance_run(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tint i;\n      \tstruct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;\n    @@ builtin/gc.c: static char const * const builtin_maintenance_register_usage[] = {\n      \n     -static int maintenance_register(int argc, const char **argv, const char *prefix)\n     +static int maintenance_register(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\t\tvoid *data UNUSED)\n      {\n      \tchar *config_file = NULL;\n      \tstruct option options[] = {\n    @@ builtin/gc.c: static char const * const builtin_maintenance_unregister_usage[] =\n      \n     -static int maintenance_unregister(int argc, const char **argv, const char *prefix)\n     +static int maintenance_unregister(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t\t  void *data UNUSED)\n      {\n      \tint force = 0;\n      \tchar *config_file = NULL;\n    @@ builtin/gc.c: static const char *const builtin_maintenance_start_usage[] = {\n      \n     -static int maintenance_start(int argc, const char **argv, const char *prefix)\n     +static int maintenance_start(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tstruct maintenance_start_opts opts = { 0 };\n      \tstruct option options[] = {\n    @@ builtin/gc.c: static int maintenance_start(int argc, const char **argv, const ch\n      \t\tdie(_(\"failed to set up maintenance schedule\"));\n      \n     -\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))\n    -+\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, repo))\n    ++\tif (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, the_repository))\n      \t\twarning(_(\"failed to add repo to global config\"));\n      \treturn 0;\n      }\n    @@ builtin/gc.c: static const char *const builtin_maintenance_stop_usage[] = {\n      \n     -static int maintenance_stop(int argc, const char **argv, const char *prefix)\n     +static int maintenance_stop(int argc, const char **argv, const char *prefix,\n    -+\t\t\t    struct repository *repo UNUSED)\n    ++\t\t\t    void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    -@@ builtin/gc.c: static const char * const builtin_maintenance_usage[] = {\n    - int cmd_maintenance(int argc,\n    - \t\t    const char **argv,\n    - \t\t    const char *prefix,\n    --\t\t    struct repository *repo UNUSED)\n    -+\t\t    struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option builtin_maintenance_options[] = {\n     @@ builtin/gc.c: int cmd_maintenance(int argc,\n      \n      \targc = parse_options(argc, argv, prefix, builtin_maintenance_options,\n      \t\t\t     builtin_maintenance_usage, 0);\n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/hook.c ##\n    @@ builtin/hook.c: static const char * const builtin_hook_run_usage[] = {\n      \n     -static int run(int argc, const char **argv, const char *prefix)\n     +static int run(int argc, const char **argv, const char *prefix,\n    -+\t       struct repository *repo UNUSED)\n    ++\t       void *data UNUSED)\n      {\n      \tint i;\n      \tstruct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;\n    -@@ builtin/hook.c: static int run(int argc, const char **argv, const char *prefix)\n    - int cmd_hook(int argc,\n    - \t     const char **argv,\n    - \t     const char *prefix,\n    --\t     struct repository *repo UNUSED)\n    -+\t     struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option builtin_hook_options[] = {\n     @@ builtin/hook.c: int cmd_hook(int argc,\n      \targc = parse_options(argc, argv, NULL, builtin_hook_options,\n      \t\t\t     builtin_hook_usage, 0);\n      \n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/multi-pack-index.c ##\n    @@ builtin/multi-pack-index.c: static void read_packs_from_stdin(struct string_list\n      \n      static int cmd_multi_pack_index_write(int argc, const char **argv,\n     -\t\t\t\t      const char *prefix)\n    -+\t\t\t\t      const char *prefix,\n    -+\t\t\t\t      struct repository *repo UNUSED)\n    ++\t\t\t\t      const char *prefix, void *data UNUSED)\n      {\n      \tstruct option *options;\n      \tstatic struct option builtin_multi_pack_index_write_options[] = {\n    @@ builtin/multi-pack-index.c: static int cmd_multi_pack_index_write(int argc, cons\n      \n      static int cmd_multi_pack_index_verify(int argc, const char **argv,\n     -\t\t\t\t       const char *prefix)\n    -+\t\t\t\t       const char *prefix,\n    -+\t\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t\t       const char *prefix, void *data UNUSED)\n      {\n      \tstruct option *options;\n      \tstatic struct option builtin_multi_pack_index_verify_options[] = {\n    @@ builtin/multi-pack-index.c: static int cmd_multi_pack_index_verify(int argc, con\n      \n      static int cmd_multi_pack_index_expire(int argc, const char **argv,\n     -\t\t\t\t       const char *prefix)\n    -+\t\t\t\t       const char *prefix,\n    -+\t\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t\t       const char *prefix, void *data UNUSED)\n      {\n      \tstruct option *options;\n      \tstatic struct option builtin_multi_pack_index_expire_options[] = {\n    @@ builtin/multi-pack-index.c: static int cmd_multi_pack_index_expire(int argc, con\n      \n      static int cmd_multi_pack_index_repack(int argc, const char **argv,\n     -\t\t\t\t       const char *prefix)\n    -+\t\t\t\t       const char *prefix,\n    -+\t\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t\t       const char *prefix, void *data UNUSED)\n      {\n      \tstruct option *options;\n      \tstatic struct option builtin_multi_pack_index_repack_options[] = {\n    -@@ builtin/multi-pack-index.c: static int cmd_multi_pack_index_repack(int argc, const char **argv,\n    - int cmd_multi_pack_index(int argc,\n    - \t\t\t const char **argv,\n    - \t\t\t const char *prefix,\n    --\t\t\t struct repository *repo UNUSED)\n    -+\t\t\t struct repository *repo)\n    - {\n    - \tint res;\n    - \tparse_opt_subcommand_fn *fn = NULL;\n     @@ builtin/multi-pack-index.c: int cmd_multi_pack_index(int argc,\n      \t\t\t     builtin_multi_pack_index_usage, 0);\n      \tFREE_AND_NULL(options);\n      \n     -\tres = fn(argc, argv, prefix);\n    -+\tres = fn(argc, argv, prefix, repo);\n    ++\tres = fn(argc, argv, prefix, NULL);\n      \n      \tfree(opts.object_dir);\n      \treturn res;\n    @@ builtin/notes.c: static struct notes_tree *init_notes_check(const char *subcomma\n      \n     -static int list(int argc, const char **argv, const char *prefix)\n     +static int list(int argc, const char **argv, const char *prefix,\n    -+\t\tstruct repository *repo UNUSED)\n    ++\t\tvoid *data UNUSED)\n      {\n      \tstruct notes_tree *t;\n      \tstruct object_id object;\n    @@ builtin/notes.c: static int list(int argc, const char **argv, const char *prefix\n      \n     -static int append_edit(int argc, const char **argv, const char *prefix);\n     +static int append_edit(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED);\n    ++\t\t       void *data UNUSED);\n      \n     -static int add(int argc, const char **argv, const char *prefix)\n     +static int add(int argc, const char **argv, const char *prefix,\n    -+\t       struct repository *repo)\n    ++\t       void *data UNUSED)\n      {\n      \tint force = 0, allow_empty = 0;\n      \tconst char *object_ref;\n    @@ builtin/notes.c: static int add(int argc, const char **argv, const char *prefix)\n      \t\t\t */\n      \t\t\targv[0] = \"edit\";\n     -\t\t\treturn append_edit(argc, argv, prefix);\n    -+\t\t\treturn append_edit(argc, argv, prefix, repo);\n    ++\t\t\treturn append_edit(argc, argv, prefix, NULL);\n      \t\t}\n      \t\tfprintf(stderr, _(\"Overwriting existing notes for object %s\\n\"),\n      \t\t\toid_to_hex(&object));\n    @@ builtin/notes.c: static int add(int argc, const char **argv, const char *prefix)\n      \n     -static int copy(int argc, const char **argv, const char *prefix)\n     +static int copy(int argc, const char **argv, const char *prefix,\n    -+\t\tstruct repository *repo UNUSED)\n    ++\t\tvoid *data UNUSED)\n      {\n      \tint retval = 0, force = 0, from_stdin = 0;\n      \tconst struct object_id *from_note, *note;\n    @@ builtin/notes.c: static int copy(int argc, const char **argv, const char *prefix\n      \n     -static int append_edit(int argc, const char **argv, const char *prefix)\n     +static int append_edit(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tint allow_empty = 0;\n      \tconst char *object_ref;\n    @@ builtin/notes.c: static int append_edit(int argc, const char **argv, const char\n      \n     -static int show(int argc, const char **argv, const char *prefix)\n     +static int show(int argc, const char **argv, const char *prefix,\n    -+\t\tstruct repository *repo UNUSED)\n    ++\t\tvoid *data UNUSED)\n      {\n      \tconst char *object_ref;\n      \tstruct notes_tree *t;\n    @@ builtin/notes.c: static int git_config_get_notes_strategy(const char *key,\n      \n     -static int merge(int argc, const char **argv, const char *prefix)\n     +static int merge(int argc, const char **argv, const char *prefix,\n    -+\t\t struct repository *repo UNUSED)\n    ++\t\t void *data UNUSED)\n      {\n      \tstruct strbuf remote_ref = STRBUF_INIT, msg = STRBUF_INIT;\n      \tstruct object_id result_oid;\n    @@ builtin/notes.c: static int remove_one_note(struct notes_tree *t, const char *na\n      \n     -static int remove_cmd(int argc, const char **argv, const char *prefix)\n     +static int remove_cmd(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tunsigned flag = 0;\n      \tint from_stdin = 0;\n    @@ builtin/notes.c: static int remove_cmd(int argc, const char **argv, const char *\n      \n     -static int prune(int argc, const char **argv, const char *prefix)\n     +static int prune(int argc, const char **argv, const char *prefix,\n    -+\t\t struct repository *repo UNUSED)\n    ++\t\t void *data UNUSED)\n      {\n      \tstruct notes_tree *t;\n      \tint show_only = 0, verbose = 0;\n    @@ builtin/notes.c: static int prune(int argc, const char **argv, const char *prefi\n      \n     -static int get_ref(int argc, const char **argv, const char *prefix)\n     +static int get_ref(int argc, const char **argv, const char *prefix,\n    -+\t\t   struct repository *repo UNUSED)\n    ++\t\t   void *data UNUSED)\n      {\n      \tstruct option options[] = { OPT_END() };\n      \tchar *notes_ref;\n    -@@ builtin/notes.c: static int get_ref(int argc, const char **argv, const char *prefix)\n    - int cmd_notes(int argc,\n    - \t      const char **argv,\n    - \t      const char *prefix,\n    --\t      struct repository *repo UNUSED)\n    -+\t      struct repository *repo)\n    - {\n    - \tconst char *override_notes_ref = NULL;\n    - \tparse_opt_subcommand_fn *fn = NULL;\n     @@ builtin/notes.c: int cmd_notes(int argc,\n      \t\tstrbuf_release(&sb);\n      \t}\n      \n     -\treturn !!fn(argc, argv, prefix);\n    -+\treturn !!fn(argc, argv, prefix, repo);\n    ++\treturn !!fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/reflog.c ##\n    @@ builtin/reflog.c: static int expire_total_callback(const struct option *opt,\n      \n     -static int cmd_reflog_show(int argc, const char **argv, const char *prefix)\n     +static int cmd_reflog_show(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    @@ builtin/reflog.c: static int show_reflog(const char *refname, void *cb_data UNUS\n      \n     -static int cmd_reflog_list(int argc, const char **argv, const char *prefix)\n     +static int cmd_reflog_list(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    @@ builtin/reflog.c: static int cmd_reflog_list(int argc, const char **argv, const\n      \n     -static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n     +static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tstruct cmd_reflog_expire_cb cmd = { 0 };\n      \ttimestamp_t now = time(NULL);\n    @@ builtin/reflog.c: static int cmd_reflog_expire(int argc, const char **argv, cons\n      \n     -static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)\n     +static int cmd_reflog_delete(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tint i, status = 0;\n      \tunsigned int flags = 0;\n    @@ builtin/reflog.c: static int cmd_reflog_delete(int argc, const char **argv, cons\n      \n     -static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)\n     +static int cmd_reflog_exists(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    +@@ builtin/reflog.c: static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)\n    + int cmd_reflog(int argc,\n    + \t       const char **argv,\n    + \t       const char *prefix,\n    +-\t       struct repository *repository)\n    ++\t       struct repository *repository UNUSED)\n    + {\n    + \tparse_opt_subcommand_fn *fn = NULL;\n    + \tstruct option options[] = {\n     @@ builtin/reflog.c: int cmd_reflog(int argc,\n      \t\t\t     PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |\n      \t\t\t     PARSE_OPT_KEEP_UNKNOWN_OPT);\n      \tif (fn)\n     -\t\treturn fn(argc - 1, argv + 1, prefix);\n    -+\t\treturn fn(argc - 1, argv + 1, prefix, repository);\n    ++\t\treturn fn(argc - 1, argv + 1, prefix, NULL);\n      \telse\n    - \t\treturn cmd_log_reflog(argc, argv, prefix, repository);\n    +-\t\treturn cmd_log_reflog(argc, argv, prefix, repository);\n    ++\t\treturn cmd_log_reflog(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/refs.c ##\n    @@ builtin/refs.c\n      \n     -static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)\n     +static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n    -+\t\t\t    struct repository *repo UNUSED)\n    ++\t\t\t    void *data UNUSED)\n      {\n      \tconst char * const migrate_usage[] = {\n      \t\tREFS_MIGRATE_USAGE,\n    @@ builtin/refs.c: static int cmd_refs_migrate(int argc, const char **argv, const c\n      \n     -static int cmd_refs_verify(int argc, const char **argv, const char *prefix)\n     +static int cmd_refs_verify(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;\n      \tconst char * const verify_usage[] = {\n    -@@ builtin/refs.c: static int cmd_refs_verify(int argc, const char **argv, const char *prefix)\n    - int cmd_refs(int argc,\n    - \t     const char **argv,\n    - \t     const char *prefix,\n    --\t     struct repository *repo UNUSED)\n    -+\t     struct repository *repo)\n    - {\n    - \tconst char * const refs_usage[] = {\n    - \t\tREFS_MIGRATE_USAGE,\n     @@ builtin/refs.c: int cmd_refs(int argc,\n      \t};\n      \n      \targc = parse_options(argc, argv, prefix, opts, refs_usage, 0);\n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/remote.c ##\n    @@ builtin/remote.c: static int parse_mirror_opt(const struct option *opt, const ch\n      \n     -static int add(int argc, const char **argv, const char *prefix)\n     +static int add(int argc, const char **argv, const char *prefix,\n    -+\t       struct repository *repo UNUSED)\n    ++\t       void *data UNUSED)\n      {\n      \tint fetch = 0, fetch_tags = TAGS_DEFAULT;\n      \tunsigned mirror = MIRROR_NONE;\n    @@ builtin/remote.c: static void handle_push_default(const char* old_name, const ch\n      \n     -static int mv(int argc, const char **argv, const char *prefix)\n     +static int mv(int argc, const char **argv, const char *prefix,\n    -+\t      struct repository *repo UNUSED)\n    ++\t      void *data UNUSED)\n      {\n      \tint show_progress = isatty(2);\n      \tstruct option options[] = {\n    @@ builtin/remote.c: static int mv(int argc, const char **argv, const char *prefix)\n      \n     -static int rm(int argc, const char **argv, const char *prefix)\n     +static int rm(int argc, const char **argv, const char *prefix,\n    -+\t      struct repository *repo UNUSED)\n    ++\t      void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    @@ builtin/remote.c: static int show_all(void)\n      \n     -static int show(int argc, const char **argv, const char *prefix)\n     +static int show(int argc, const char **argv, const char *prefix,\n    -+\t\tstruct repository *repo UNUSED)\n    ++\t\tvoid *data UNUSED)\n      {\n      \tint no_query = 0, result = 0, query_flag = 0;\n      \tstruct option options[] = {\n    @@ builtin/remote.c: static int show(int argc, const char **argv, const char *prefi\n      \n     -static int set_head(int argc, const char **argv, const char *prefix)\n     +static int set_head(int argc, const char **argv, const char *prefix,\n    -+\t\t    struct repository *repo UNUSED)\n    ++\t\t    void *data UNUSED)\n      {\n      \tint i, opt_a = 0, opt_d = 0, result = 0;\n      \tstruct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;\n    @@ builtin/remote.c: static int prune_remote(const char *remote, int dry_run)\n      \n     -static int prune(int argc, const char **argv, const char *prefix)\n     +static int prune(int argc, const char **argv, const char *prefix,\n    -+\t\t struct repository *repo UNUSED)\n    ++\t\t void *data UNUSED)\n      {\n      \tint dry_run = 0, result = 0;\n      \tstruct option options[] = {\n    @@ builtin/remote.c: static int get_remote_default(const char *key, const char *val\n      \n     -static int update(int argc, const char **argv, const char *prefix)\n     +static int update(int argc, const char **argv, const char *prefix,\n    -+\t\t  struct repository *repo UNUSED)\n    ++\t\t  void *data UNUSED)\n      {\n      \tint i, prune = -1;\n      \tstruct option options[] = {\n    @@ builtin/remote.c: static int set_remote_branches(const char *remotename, const c\n      \n     -static int set_branches(int argc, const char **argv, const char *prefix)\n     +static int set_branches(int argc, const char **argv, const char *prefix,\n    -+\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\tvoid *data UNUSED)\n      {\n      \tint add_mode = 0;\n      \tstruct option options[] = {\n    @@ builtin/remote.c: static int set_branches(int argc, const char **argv, const cha\n      \n     -static int get_url(int argc, const char **argv, const char *prefix)\n     +static int get_url(int argc, const char **argv, const char *prefix,\n    -+\t\t   struct repository *repo UNUSED)\n    ++\t\t   void *data UNUSED)\n      {\n      \tint i, push_mode = 0, all_mode = 0;\n      \tconst char *remotename = NULL;\n    @@ builtin/remote.c: static int get_url(int argc, const char **argv, const char *pr\n      \n     -static int set_url(int argc, const char **argv, const char *prefix)\n     +static int set_url(int argc, const char **argv, const char *prefix,\n    -+\t\t   struct repository *repo UNUSED)\n    ++\t\t   void *data UNUSED)\n      {\n      \tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n      \tint matches = 0, negative_matches = 0;\n    -@@ builtin/remote.c: static int set_url(int argc, const char **argv, const char *prefix)\n    - int cmd_remote(int argc,\n    - \t       const char **argv,\n    - \t       const char *prefix,\n    --\t       struct repository *repo UNUSED)\n    -+\t       struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option options[] = {\n     @@ builtin/remote.c: int cmd_remote(int argc,\n      \t\t\t     PARSE_OPT_SUBCOMMAND_OPTIONAL);\n      \n      \tif (fn) {\n     -\t\treturn !!fn(argc, argv, prefix);\n    -+\t\treturn !!fn(argc, argv, prefix, repo);\n    ++\t\treturn !!fn(argc, argv, prefix, NULL);\n      \t} else {\n      \t\tif (argc) {\n      \t\t\terror(_(\"unknown subcommand: `%s'\"), argv[0]);\n    @@ builtin/sparse-checkout.c: static char const * const builtin_sparse_checkout_lis\n      \n     -static int sparse_checkout_list(int argc, const char **argv, const char *prefix)\n     +static int sparse_checkout_list(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\t\tvoid *data UNUSED)\n      {\n      \tstatic struct option builtin_sparse_checkout_list_options[] = {\n      \t\tOPT_END(),\n    @@ builtin/sparse-checkout.c: static struct sparse_checkout_init_opts {\n      \n     -static int sparse_checkout_init(int argc, const char **argv, const char *prefix)\n     +static int sparse_checkout_init(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\t\tvoid *data UNUSED)\n      {\n      \tstruct pattern_list pl;\n      \tchar *sparse_filename;\n    @@ builtin/sparse-checkout.c: static struct sparse_checkout_add_opts {\n      \n     -static int sparse_checkout_add(int argc, const char **argv, const char *prefix)\n     +static int sparse_checkout_add(int argc, const char **argv, const char *prefix,\n    -+\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t       void *data UNUSED)\n      {\n      \tstatic struct option builtin_sparse_checkout_add_options[] = {\n      \t\tOPT_BOOL_F(0, \"skip-checks\", &add_opts.skip_checks,\n    @@ builtin/sparse-checkout.c: static struct sparse_checkout_set_opts {\n      \n     -static int sparse_checkout_set(int argc, const char **argv, const char *prefix)\n     +static int sparse_checkout_set(int argc, const char **argv, const char *prefix,\n    -+\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t       void *data UNUSED)\n      {\n      \tint default_patterns_nr = 2;\n      \tconst char *default_patterns[] = {\"/*\", \"!/*/\", NULL};\n    @@ builtin/sparse-checkout.c: static struct sparse_checkout_reapply_opts {\n      \n      static int sparse_checkout_reapply(int argc, const char **argv,\n     -\t\t\t\t   const char *prefix)\n    -+\t\t\t\t   const char *prefix,\n    -+\t\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t\t   const char *prefix, void *data UNUSED)\n      {\n      \tstatic struct option builtin_sparse_checkout_reapply_options[] = {\n      \t\tOPT_BOOL(0, \"cone\", &reapply_opts.cone_mode,\n    @@ builtin/sparse-checkout.c: static char const * const builtin_sparse_checkout_dis\n      \n      static int sparse_checkout_disable(int argc, const char **argv,\n     -\t\t\t\t   const char *prefix)\n    -+\t\t\t\t   const char *prefix,\n    -+\t\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t\t   const char *prefix, void *data UNUSED)\n      {\n      \tstatic struct option builtin_sparse_checkout_disable_options[] = {\n      \t\tOPT_END(),\n    @@ builtin/sparse-checkout.c: static int check_rules(struct pattern_list *pl, int n\n      \n     -static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)\n     +static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\t       struct repository *repo UNUSED)\n    ++\t\t\t\t       void *data UNUSED)\n      {\n      \tstatic struct option builtin_sparse_checkout_check_rules_options[] = {\n      \t\tOPT_BOOL('z', NULL, &check_rules_opts.null_termination,\n    -@@ builtin/sparse-checkout.c: static int sparse_checkout_check_rules(int argc, const char **argv, const char *\n    - int cmd_sparse_checkout(int argc,\n    - \t\t\tconst char **argv,\n    - \t\t\tconst char *prefix,\n    --\t\t\tstruct repository *repo UNUSED)\n    -+\t\t\tstruct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option builtin_sparse_checkout_options[] = {\n     @@ builtin/sparse-checkout.c: int cmd_sparse_checkout(int argc,\n      \tprepare_repo_settings(the_repository);\n      \tthe_repository->settings.command_requires_full_index = 0;\n      \n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/stash.c ##\n    @@ builtin/stash.c: static int do_clear_stash(void)\n      \n     -static int clear_stash(int argc, const char **argv, const char *prefix)\n     +static int clear_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    @@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info\n      \n     -static int apply_stash(int argc, const char **argv, const char *prefix)\n     +static int apply_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tint ret = -1;\n      \tint quiet = 0;\n    @@ builtin/stash.c: static int get_stash_info_assert(struct stash_info *info, int a\n      \n     -static int drop_stash(int argc, const char **argv, const char *prefix)\n     +static int drop_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tint ret = -1;\n      \tint quiet = 0;\n    @@ builtin/stash.c: static int drop_stash(int argc, const char **argv, const char *\n      \n     -static int pop_stash(int argc, const char **argv, const char *prefix)\n     +static int pop_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t     struct repository *repo UNUSED)\n    ++\t\t     void *data UNUSED)\n      {\n      \tint ret = -1;\n      \tint index = 0;\n    @@ builtin/stash.c: static int pop_stash(int argc, const char **argv, const char *p\n      \n     -static int branch_stash(int argc, const char **argv, const char *prefix)\n     +static int branch_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\tvoid *data UNUSED)\n      {\n      \tint ret = -1;\n      \tconst char *branch = NULL;\n    @@ builtin/stash.c: static int branch_stash(int argc, const char **argv, const char\n      \n     -static int list_stash(int argc, const char **argv, const char *prefix)\n     +static int list_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tstruct child_process cp = CHILD_PROCESS_INIT;\n      \tstruct option options[] = {\n    @@ builtin/stash.c: static void diff_include_untracked(const struct stash_info *inf\n      \n     -static int show_stash(int argc, const char **argv, const char *prefix)\n     +static int show_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tint i;\n      \tint ret = -1;\n    @@ builtin/stash.c: static int do_store_stash(const struct object_id *w_commit, con\n      \n     -static int store_stash(int argc, const char **argv, const char *prefix)\n     +static int store_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tint quiet = 0;\n      \tconst char *stash_msg = NULL;\n    @@ builtin/stash.c: static int do_create_stash(const struct pathspec *ps, struct st\n      \n     -static int create_stash(int argc, const char **argv, const char *prefix UNUSED)\n     +static int create_stash(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\tvoid *data UNUSED)\n      {\n      \tint ret;\n      \tstruct strbuf stash_msg_buf = STRBUF_INIT;\n    @@ builtin/stash.c: static int push_stash(int argc, const char **argv, const char *\n      \n     -static int push_stash_unassumed(int argc, const char **argv, const char *prefix)\n     +static int push_stash_unassumed(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\t\tvoid *data UNUSED)\n      {\n      \treturn push_stash(argc, argv, prefix, 0);\n      }\n      \n     -static int save_stash(int argc, const char **argv, const char *prefix)\n     +static int save_stash(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tint keep_index = -1;\n      \tint only_staged = 0;\n    -@@ builtin/stash.c: static int save_stash(int argc, const char **argv, const char *prefix)\n    - int cmd_stash(int argc,\n    - \t      const char **argv,\n    - \t      const char *prefix,\n    --\t      struct repository *repo UNUSED)\n    -+\t      struct repository *repo)\n    - {\n    - \tpid_t pid = getpid();\n    - \tconst char *index_file;\n     @@ builtin/stash.c: int cmd_stash(int argc,\n      \t\t    (uintmax_t)pid);\n      \n      \tif (fn)\n     -\t\treturn !!fn(argc, argv, prefix);\n    -+\t\treturn !!fn(argc, argv, prefix, repo);\n    ++\t\treturn !!fn(argc, argv, prefix, NULL);\n      \telse if (!argc)\n     -\t\treturn !!push_stash_unassumed(0, NULL, prefix);\n    -+\t\treturn !!push_stash_unassumed(0, NULL, prefix, repo);\n    ++\t\treturn !!push_stash_unassumed(0, NULL, prefix, NULL);\n      \n      \t/* Assume 'stash push' */\n      \tstrvec_push(&args, \"push\");\n    @@ builtin/submodule--helper.c: static void runcommand_in_submodule_cb(const struct\n      \n     -static int module_foreach(int argc, const char **argv, const char *prefix)\n     +static int module_foreach(int argc, const char **argv, const char *prefix,\n    -+\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t  void *data UNUSED)\n      {\n      \tstruct foreach_cb info = FOREACH_CB_INIT;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static void init_submodule_cb(const struct cache_en\n      \n     -static int module_init(int argc, const char **argv, const char *prefix)\n     +static int module_init(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tstruct init_cb info = INIT_CB_INIT;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static void status_submodule_cb(const struct cache_\n      \n     -static int module_status(int argc, const char **argv, const char *prefix)\n     +static int module_status(int argc, const char **argv, const char *prefix,\n    -+\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t void *data UNUSED)\n      {\n      \tstruct status_cb info = STATUS_CB_INIT;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static int compute_summary_module_list(struct objec\n      \n     -static int module_summary(int argc, const char **argv, const char *prefix)\n     +static int module_summary(int argc, const char **argv, const char *prefix,\n    -+\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t  void *data UNUSED)\n      {\n      \tstruct summary_cb info = SUMMARY_CB_INIT;\n      \tint cached = 0;\n    @@ builtin/submodule--helper.c: static void sync_submodule_cb(const struct cache_en\n      \n     -static int module_sync(int argc, const char **argv, const char *prefix)\n     +static int module_sync(int argc, const char **argv, const char *prefix,\n    -+\t\t       struct repository *repo UNUSED)\n    ++\t\t       void *data UNUSED)\n      {\n      \tstruct sync_cb info = SYNC_CB_INIT;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static void deinit_submodule_cb(const struct cache_\n      \n     -static int module_deinit(int argc, const char **argv, const char *prefix)\n     +static int module_deinit(int argc, const char **argv, const char *prefix,\n    -+\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t void *data UNUSED)\n      {\n      \tstruct deinit_cb info = DEINIT_CB_INIT;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static int clone_submodule(const struct module_clon\n      \n     -static int module_clone(int argc, const char **argv, const char *prefix)\n     +static int module_clone(int argc, const char **argv, const char *prefix,\n    -+\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\tvoid *data UNUSED)\n      {\n      \tint dissociate = 0, quiet = 0, progress = 0, require_init = 0;\n      \tstruct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;\n    @@ builtin/submodule--helper.c: static int update_submodules(struct update_data *up\n      \n     -static int module_update(int argc, const char **argv, const char *prefix)\n     +static int module_update(int argc, const char **argv, const char *prefix,\n    -+\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t void *data UNUSED)\n      {\n      \tstruct pathspec pathspec = { 0 };\n      \tstruct pathspec pathspec2 = { 0 };\n    @@ builtin/submodule--helper.c: static int module_update(int argc, const char **arg\n      \n     -static int push_check(int argc, const char **argv, const char *prefix UNUSED)\n     +static int push_check(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tstruct remote *remote;\n      \tconst char *superproject_head;\n    @@ builtin/submodule--helper.c: static int push_check(int argc, const char **argv,\n      \n     -static int absorb_git_dirs(int argc, const char **argv, const char *prefix)\n     +static int absorb_git_dirs(int argc, const char **argv, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tint i;\n      \tstruct pathspec pathspec = { 0 };\n    @@ builtin/submodule--helper.c: static int absorb_git_dirs(int argc, const char **a\n      \n     -static int module_set_url(int argc, const char **argv, const char *prefix)\n     +static int module_set_url(int argc, const char **argv, const char *prefix,\n    -+\t\t\t  struct repository *repo UNUSED)\n    ++\t\t\t  void *data UNUSED)\n      {\n      \tint quiet = 0, ret;\n      \tconst char *newurl;\n    @@ builtin/submodule--helper.c: static int module_set_url(int argc, const char **ar\n      \n     -static int module_set_branch(int argc, const char **argv, const char *prefix)\n     +static int module_set_branch(int argc, const char **argv, const char *prefix,\n    -+\t\t\t     struct repository *repo UNUSED)\n    ++\t\t\t     void *data UNUSED)\n      {\n      \tint opt_default = 0, ret;\n      \tconst char *opt_branch = NULL;\n    @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char *\n      \n     -static int module_create_branch(int argc, const char **argv, const char *prefix)\n     +static int module_create_branch(int argc, const char **argv, const char *prefix,\n    -+\t\t\t\tstruct repository *repo UNUSED)\n    ++\t\t\t\tvoid *data UNUSED)\n      {\n      \tenum branch_track track;\n      \tint quiet = 0, force = 0, reflog = 0, dry_run = 0;\n    @@ builtin/submodule--helper.c: static void die_on_repo_without_commits(const char\n      \n     -static int module_add(int argc, const char **argv, const char *prefix)\n     +static int module_add(int argc, const char **argv, const char *prefix,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tint force = 0, quiet = 0, progress = 0, dissociate = 0;\n      \tstruct add_data add_data = ADD_DATA_INIT;\n    -@@ builtin/submodule--helper.c: static int module_add(int argc, const char **argv, const char *prefix)\n    - int cmd_submodule__helper(int argc,\n    - \t\t\t  const char **argv,\n    - \t\t\t  const char *prefix,\n    --\t\t\t  struct repository *repo UNUSED)\n    -+\t\t\t  struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tconst char *const usage[] = {\n     @@ builtin/submodule--helper.c: int cmd_submodule__helper(int argc,\n      \t};\n      \targc = parse_options(argc, argv, prefix, options, usage, 0);\n      \n     -\treturn fn(argc, argv, prefix);\n    -+\treturn fn(argc, argv, prefix, repo);\n    ++\treturn fn(argc, argv, prefix, NULL);\n      }\n     \n      ## builtin/worktree.c ##\n    @@ builtin/worktree.c: static void prune_worktrees(void)\n      \n     -static int prune(int ac, const char **av, const char *prefix)\n     +static int prune(int ac, const char **av, const char *prefix,\n    -+\t\t struct repository *repo UNUSED)\n    ++\t\t void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT__DRY_RUN(&show_only, N_(\"do not remove, show only\")),\n    @@ builtin/worktree.c: static char *dwim_branch(const char *path, char **new_branch\n      \n     -static int add(int ac, const char **av, const char *prefix)\n     +static int add(int ac, const char **av, const char *prefix,\n    -+\t       struct repository *repo UNUSED)\n    ++\t       void *data UNUSED)\n      {\n      \tstruct add_opts opts;\n      \tconst char *new_branch_force = NULL;\n    @@ builtin/worktree.c: static void pathsort(struct worktree **wt)\n      \n     -static int list(int ac, const char **av, const char *prefix)\n     +static int list(int ac, const char **av, const char *prefix,\n    -+\t\tstruct repository *repo UNUSED)\n    ++\t\tvoid *data UNUSED)\n      {\n      \tint porcelain = 0;\n      \tint line_terminator = '\\n';\n    @@ builtin/worktree.c: static int list(int ac, const char **av, const char *prefix)\n      \n     -static int lock_worktree(int ac, const char **av, const char *prefix)\n     +static int lock_worktree(int ac, const char **av, const char *prefix,\n    -+\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t void *data UNUSED)\n      {\n      \tconst char *reason = \"\", *old_reason;\n      \tstruct option options[] = {\n    @@ builtin/worktree.c: static int lock_worktree(int ac, const char **av, const char\n      \n     -static int unlock_worktree(int ac, const char **av, const char *prefix)\n     +static int unlock_worktree(int ac, const char **av, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tstruct option options[] = {\n      \t\tOPT_END()\n    @@ builtin/worktree.c: static void validate_no_submodules(const struct worktree *wt\n      \n     -static int move_worktree(int ac, const char **av, const char *prefix)\n     +static int move_worktree(int ac, const char **av, const char *prefix,\n    -+\t\t\t struct repository *repo UNUSED)\n    ++\t\t\t void *data UNUSED)\n      {\n      \tint force = 0;\n      \tstruct option options[] = {\n    @@ builtin/worktree.c: static int delete_git_work_tree(struct worktree *wt)\n      \n     -static int remove_worktree(int ac, const char **av, const char *prefix)\n     +static int remove_worktree(int ac, const char **av, const char *prefix,\n    -+\t\t\t   struct repository *repo UNUSED)\n    ++\t\t\t   void *data UNUSED)\n      {\n      \tint force = 0;\n      \tstruct option options[] = {\n    @@ builtin/worktree.c: static void report_repair(int iserr, const char *path, const\n      \n     -static int repair(int ac, const char **av, const char *prefix)\n     +static int repair(int ac, const char **av, const char *prefix,\n    -+\t\t  struct repository *repo UNUSED)\n    ++\t\t  void *data UNUSED)\n      {\n      \tconst char **p;\n      \tconst char *self[] = { \".\", NULL };\n    -@@ builtin/worktree.c: static int repair(int ac, const char **av, const char *prefix)\n    - int cmd_worktree(int ac,\n    - \t\t const char **av,\n    - \t\t const char *prefix,\n    --\t\t struct repository *repo UNUSED)\n    -+\t\t struct repository *repo)\n    - {\n    - \tparse_opt_subcommand_fn *fn = NULL;\n    - \tstruct option options[] = {\n     @@ builtin/worktree.c: int cmd_worktree(int ac,\n      \tprepare_repo_settings(the_repository);\n      \tthe_repository->settings.command_requires_full_index = 0;\n      \n     -\treturn fn(ac, av, prefix);\n    -+\treturn fn(ac, av, prefix, repo);\n    ++\treturn fn(ac, av, prefix, NULL);\n      }\n     \n      ## parse-options.h ##\n    -@@\n    - \n    - #include \"gettext.h\"\n    - \n    -+struct repository;\n    -+\n    - /**\n    -  * Refer to Documentation/technical/api-parse-options.txt for the API doc.\n    -  */\n     @@ parse-options.h: typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,\n      \t\t\t\t\t      const char *arg, int unset);\n      \n      typedef int parse_opt_subcommand_fn(int argc, const char **argv,\n     -\t\t\t\t    const char *prefix);\n    -+\t\t\t\t    const char *prefix, struct repository *repo);\n    ++\t\t\t\t    const char *prefix, void *data);\n      \n      /*\n       * `type`::\n    @@ t/helper/test-parse-options.c: int cmd__parse_options_flags(int argc, const char\n      \n     -static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED)\n     +static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tprintf(\"fn: subcmd_one\\n\");\n      \tprint_args(argc, argv);\n    @@ t/helper/test-parse-options.c: int cmd__parse_options_flags(int argc, const char\n      \n     -static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED)\n     +static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED,\n    -+\t\t      struct repository *repo UNUSED)\n    ++\t\t      void *data UNUSED)\n      {\n      \tprintf(\"fn: subcmd_two\\n\");\n      \tprint_args(argc, argv);\n\n\n--- \n\nbase-commit: 04eaff62f286226f501dd21f069e0e257aee11a6\nchange-id: 20241122-374-add-repository-to-subsubcommands-226a391d95c7\n\nThanks\n- Karthik\n\n"},{"id":"508183","messageId":"Z0W3rgHQhmUxjgfp@ArchLinux","threadId":"62542","inReplyTo":"20241126-374-add-repository-to-subsubcommands-v2-1-417e0dc66c75@gmail.com","subject":"Re: [PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2024-11-26T11:57:34Z","receivedAt":"2024-11-26T11:57:18Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Tue, Nov 26, 2024 at 12:19:22PM +0100, Karthik Nayak wrote:\n> In 9b1cb5070f (builtin: add a repository parameter for builtin\n> functions, 2024-09-13) the repository was passed down to all builtin\n> commands. This allowed the repository to be passed down to lower layers\n> without depending on the global `the_repository` variable.\n> \n> To remove usage of global variables like `the_repository` in\n> sub-commands, it makes sense to pass down the repository value from the\n> commands to the sub-commands. But let's make it more generic and modify\n> `parse_opt_subcommand_fn` to instead take a `void *` value. This way we\n> can provide custom structures to each sub-command.\n> \n\nFrom my perspective, I think using either \"struct repository *\" or \"void\n*\" is OK. However, I am a little concerned about using \"void *\" at\ncurrent. It gives me a feeling that we over-optimize here.\n\nThanks,\nJialuo\n"},{"id":"508188","messageId":"CAOLa=ZTeRUT6Ex5Pa-fM1i-QbTfnmDN=o=MU_N2VFeLQwbscgg@mail.gmail.com","threadId":"62542","inReplyTo":"Z0W3rgHQhmUxjgfp@ArchLinux","subject":"Re: [PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-26T16:41:04Z","receivedAt":"2024-11-26T16:41:07Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"shejialuo <shejialuo@gmail.com> writes:\n\n> On Tue, Nov 26, 2024 at 12:19:22PM +0100, Karthik Nayak wrote:\n>> In 9b1cb5070f (builtin: add a repository parameter for builtin\n>> functions, 2024-09-13) the repository was passed down to all builtin\n>> commands. This allowed the repository to be passed down to lower layers\n>> without depending on the global `the_repository` variable.\n>>\n>> To remove usage of global variables like `the_repository` in\n>> sub-commands, it makes sense to pass down the repository value from the\n>> commands to the sub-commands. But let's make it more generic and modify\n>> `parse_opt_subcommand_fn` to instead take a `void *` value. This way we\n>> can provide custom structures to each sub-command.\n>>\n>\n> From my perspective, I think using either \"struct repository *\" or \"void\n> *\" is OK. However, I am a little concerned about using \"void *\" at\n> current. It gives me a feeling that we over-optimize here.\n>\n\nCould you elaborate on why you think this is an over-optimization? We\ndon't loose functionality with this, nor do we have to have add\nadditional code to handle the typecasting to `struct repository *` if\nneeded. But would definitely like to resolve anything I missed.\n"},{"id":"508191","messageId":"xmqq34jdyey3.fsf@gitster.g","threadId":"62542","inReplyTo":"Z0WNKV5prRE2Hupw@pks.im","subject":"Re: [PATCH] builtin: pass repository to sub commands","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-11-26T19:26:12Z","receivedAt":"2024-11-26T19:26:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> So if the code were refactored to instead accept an arbitrary `void *`\n> pointer, callers could provide a custom structure and pass that along to\n> its subcommands. In many cases we may end up just passing the repo\n> directly, but I'm sure there are others where this direction would buy\n> us additional flexibility and allow us to get rid of even more global\n> state.\n\nI am of two minds.  Certainly for OPT_SUBCOMMAND macro to be able to\nwork with arbitrary types that are specific to each git subcommand,\nwe'd need \"void *\" plus casting on the receiving end.  But it loses\ntype safety.\n\nI personally think (but not so strongly) that we should add a repo\nto parse_opt_subcommand_fn(), if this exercise is about giving\nconsistent access to the repository object universally across\nsubsubcommands.\n\nIf we want flexibility on top, we can either add another \"void *\"\nfor it after we are done with adding the repository, or we may even\nbe able to make the parse_opt_subcommand_fn() a varargs.\n\n"},{"id":"508192","messageId":"xmqqy115x0be.fsf@gitster.g","threadId":"62542","inReplyTo":"CAOLa=ZTeRUT6Ex5Pa-fM1i-QbTfnmDN=o=MU_N2VFeLQwbscgg@mail.gmail.com","subject":"Re: [PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-11-26T19:27:33Z","receivedAt":"2024-11-26T19:27:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"karthik nayak <karthik.188@gmail.com> writes:\n\n> Could you elaborate on why you think this is an over-optimization? We\n> don't loose functionality with this, nor do we have to have add\n> additional code to handle the typecasting to `struct repository *` if\n> needed. But would definitely like to resolve anything I missed.\n\nI do not know if it is an optimization, but if you know it is of a\nspecific type, casting back and force with \"void *\" loses type\nsafety, no?\n"},{"id":"508218","messageId":"CAOLa=ZQgKv4SEPRqQix8pJo1nr30Fpg2oF-LdDX1ynHeSjDcGw@mail.gmail.com","threadId":"62542","inReplyTo":"xmqqy115x0be.fsf@gitster.g","subject":"Re: [PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-27T09:15:59Z","receivedAt":"2024-11-27T09:16:01Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> karthik nayak <karthik.188@gmail.com> writes:\n>\n>> Could you elaborate on why you think this is an over-optimization? We\n>> don't loose functionality with this, nor do we have to have add\n>> additional code to handle the typecasting to `struct repository *` if\n>> needed. But would definitely like to resolve anything I missed.\n>\n> I do not know if it is an optimization, but if you know it is of a\n> specific type, casting back and force with \"void *\" loses type\n> safety, no?\n\nThat is true of course, I just thought that is the price to pay in C for\nhaving to deal with generic data propagation. In the end I'm okay with\nboth scenarios, I see merits both ways. I do tend to incline on the\ngeneric version in v2, since it is a lot more expandable.\n"},{"id":"508223","messageId":"CAOLa=ZRj8SiZu3AiBTGHwp+SiuBNBj3VAsVG9PppTjyKuz9oyA@mail.gmail.com","threadId":"62542","inReplyTo":"CAOLa=ZQgKv4SEPRqQix8pJo1nr30Fpg2oF-LdDX1ynHeSjDcGw@mail.gmail.com","subject":"Re: [PATCH v2] builtin: allow passing custom data to sub-commands","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-11-27T12:23:07Z","receivedAt":"2024-11-27T12:23:09Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"karthik nayak <karthik.188@gmail.com> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> karthik nayak <karthik.188@gmail.com> writes:\n>>\n>>> Could you elaborate on why you think this is an over-optimization? We\n>>> don't loose functionality with this, nor do we have to have add\n>>> additional code to handle the typecasting to `struct repository *` if\n>>> needed. But would definitely like to resolve anything I missed.\n>>\n>> I do not know if it is an optimization, but if you know it is of a\n>> specific type, casting back and force with \"void *\" loses type\n>> safety, no?\n>\n> That is true of course, I just thought that is the price to pay in C for\n> having to deal with generic data propagation. In the end I'm okay with\n> both scenarios, I see merits both ways. I do tend to incline on the\n> generic version in v2, since it is a lot more expandable.\n\nThat said, I see v1 is merged into `next` [1]. I think we should keep it\nthat way and like you said modify it in the future if needed to add\nvarargs or another `void *` argument.\n\nThanks\n\n[1]: https://github.com/gitster/git/commit/668c0913f5803ebcc3b0b1f13e6cd49503194869\n"}]}