setup: make ref storage format configurable via config

Similar to the preceding commit, introduce a new "init.defaultRefFormat" config that allows the user to globally set the ref storage format used by newly created repositories. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Aug 16, 2024 at 10:57 UTC d2511eeae5fc679cf1b1591b3604e6abf5c056c2
3 files changed +63
Documentation/config/init.txt
+5
@@ -13,3 +13,8 @@ endif::[]
13 `--object-format=` in linkgit:git-init[1]. Both the command line option
14 and the `GIT_DEFAULT_HASH` environment variable take precedence over
15 this config.
16 +`init.defaultRefFormat`::
17 + Allows overriding the default ref storage format for new repositories.
18 + See `--ref-format=` in linkgit:git-init[1]. Both the command line
19 + option and the `GIT_DEFAULT_REF_FORMAT` environment variable take
20 + precedence over this config.
setup.c
+14
@@ -2286,6 +2286,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link)
2286
2287 struct default_format_config {
2288 int hash;
2289 + enum ref_storage_format ref_format;
2290 };
2291
2292 static int read_default_format_config(const char *key, const char *value,
@@ -2306,6 +2307,16 @@ static int read_default_format_config(const char *key, const char *value,
2307 goto out;
2308 }
2309
2310 + if (!strcmp(key, "init.defaultrefformat")) {
2311 + ret = git_config_string(&str, key, value);
2312 + if (ret)
2313 + goto out;
2314 + cfg->ref_format = ref_storage_format_by_name(str);
2315 + if (cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN)
2316 + warning(_("unknown ref storage format '%s'"), str);
2317 + goto out;
2318 + }
2319 +
2320 ret = 0;
2321 out:
2322 free(str);
@@ -2317,6 +2328,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,
2328 {
2329 struct default_format_config cfg = {
2330 .hash = GIT_HASH_UNKNOWN,
2331 + .ref_format = REF_STORAGE_FORMAT_UNKNOWN,
2332 };
2333 struct config_options opts = {
2334 .respect_includes = 1,
@@ -2359,6 +2371,8 @@ static void repository_format_configure(struct repository_format *repo_fmt,
2371 if (ref_format == REF_STORAGE_FORMAT_UNKNOWN)
2372 die(_("unknown ref storage format '%s'"), env);
2373 repo_fmt->ref_storage_format = ref_format;
2374 + } else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
2375 + repo_fmt->ref_storage_format = cfg.ref_format;
2376 }
2377 repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format);
2378 }
t/t0001-init.sh
+44
@@ -620,6 +620,19 @@ test_expect_success 'init with GIT_DEFAULT_REF_FORMAT=garbage' '
620 test_cmp expect err
621 '
622
623 +test_expect_success 'init warns about invalid init.defaultRefFormat' '
624 + test_when_finished "rm -rf repo" &&
625 + test_config_global init.defaultRefFormat garbage &&
626 +
627 + echo "warning: unknown ref storage format ${SQ}garbage${SQ}" >expect &&
628 + git init repo 2>err &&
629 + test_cmp expect err &&
630 +
631 + git -C repo rev-parse --show-ref-format >actual &&
632 + echo $GIT_DEFAULT_REF_FORMAT >expected &&
633 + test_cmp expected actual
634 +'
635 +
636 backends="files reftable"
637 for format in $backends
638 do
@@ -650,6 +663,27 @@ do
663 git -C refformat rev-parse --show-ref-format >actual &&
664 test_cmp expect actual
665 '
666 +
667 + test_expect_success "init with init.defaultRefFormat=$format" '
668 + test_when_finished "rm -rf refformat" &&
669 + test_config_global init.defaultRefFormat $format &&
670 + (
671 + sane_unset GIT_DEFAULT_REF_FORMAT &&
672 + git init refformat
673 + ) &&
674 +
675 + echo $format >expect &&
676 + git -C refformat rev-parse --show-ref-format >actual &&
677 + test_cmp expect actual
678 + '
679 +
680 + test_expect_success "--ref-format=$format overrides GIT_DEFAULT_REF_FORMAT" '
681 + test_when_finished "rm -rf refformat" &&
682 + GIT_DEFAULT_REF_FORMAT=garbage git init --ref-format=$format refformat &&
683 + echo $format >expect &&
684 + git -C refformat rev-parse --show-ref-format >actual &&
685 + test_cmp expect actual
686 + '
687 done
688
689 test_expect_success "--ref-format= overrides GIT_DEFAULT_REF_FORMAT" '
@@ -660,6 +694,16 @@ test_expect_success "--ref-format= overrides GIT_DEFAULT_REF_FORMAT" '
694 test_cmp expect actual
695 '
696
697 +test_expect_success "GIT_DEFAULT_REF_FORMAT= overrides init.defaultRefFormat" '
698 + test_when_finished "rm -rf refformat" &&
699 + test_config_global init.defaultRefFormat files &&
700 +
701 + GIT_DEFAULT_REF_FORMAT=reftable git init refformat &&
702 + echo reftable >expect &&
703 + git -C refformat rev-parse --show-ref-format >actual &&
704 + test_cmp expect actual
705 +'
706 +
707 for from_format in $backends
708 do
709 test_expect_success "re-init with same format ($from_format)" '