checkout/fetch/pull/pack-objects: allow `-h` outside a repository

When we taught these commands about the sparse index, we did not account for the fact that the `cmd_*()` functions _can_ be called without a gitdir, namely when `-h` is passed to show the usage. A plausible approach to address this is to move the `prepare_repo_settings()` calls right after the `parse_options()` calls: The latter will never return when it handles `-h`, and therefore it is safe to assume that we have a `gitdir` at that point, as long as the built-in is marked with the `RUN_SETUP` flag. However, it is unfortunately not that simple. In `cmd_pack_objects()`, for example, the repo settings need to be fully populated so that the command-line options `--sparse`/`--no-sparse` can override them, not the other way round. Therefore, we choose to imitate the strategy taken in `cmd_diff()`, where we simply do not bother to prepare and initialize the repo settings unless we have a `gitdir`. This fixes https://github.com/git-for-windows/git/issues/3688 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Feb 8, 2022 at 11:21 UTC 059fda190215d18e7aa23f825cd607b16a016b65
4 files changed +17 -10
builtin/checkout.c
+4 -3
@@ -1602,9 +1602,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
1602 opts->show_progress = -1;
1603
1604 git_config(git_checkout_config, opts);
1605 -
1606 - prepare_repo_settings(the_repository);
1607 - the_repository->settings.command_requires_full_index = 0;
1605 + if (the_repository->gitdir) {
1606 + prepare_repo_settings(the_repository);
1607 + the_repository->settings.command_requires_full_index = 0;
1608 + }
1609
1610 opts->track = BRANCH_TRACK_UNSPECIFIED;
1611
builtin/fetch.c
+4 -2
@@ -2014,8 +2014,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
2014 }
2015
2016 git_config(git_fetch_config, NULL);
2017 - prepare_repo_settings(the_repository);
2018 - the_repository->settings.command_requires_full_index = 0;
2017 + if (the_repository->gitdir) {
2018 + prepare_repo_settings(the_repository);
2019 + the_repository->settings.command_requires_full_index = 0;
2020 + }
2021
2022 argc = parse_options(argc, argv, prefix,
2023 builtin_fetch_options, builtin_fetch_usage, 0);
builtin/pack-objects.c
+5 -3
@@ -3976,9 +3976,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
3976 read_replace_refs = 0;
3977
3978 sparse = git_env_bool("GIT_TEST_PACK_SPARSE", -1);
3979 - prepare_repo_settings(the_repository);
3980 - if (sparse < 0)
3981 - sparse = the_repository->settings.pack_use_sparse;
3979 + if (the_repository->gitdir) {
3980 + prepare_repo_settings(the_repository);
3981 + if (sparse < 0)
3982 + sparse = the_repository->settings.pack_use_sparse;
3983 + }
3984
3985 reset_pack_idx_option(&pack_idx_opts);
3986 git_config(git_pack_config, NULL);
builtin/pull.c
+4 -2
@@ -994,8 +994,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
994 set_reflog_message(argc, argv);
995
996 git_config(git_pull_config, NULL);
997 - prepare_repo_settings(the_repository);
998 - the_repository->settings.command_requires_full_index = 0;
997 + if (the_repository->gitdir) {
998 + prepare_repo_settings(the_repository);
999 + the_repository->settings.command_requires_full_index = 0;
1000 + }
1001
1002 argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
1003