environment: stop storing "core.warnAmbiguousRefs" globally

Same as the preceding commits, storing the "core.warnAmbiguousRefs" value globally is misdesigned as this setting may be set per repository. Move the logic into the repo-settings subsystem. The usual pattern here is that users are expected to call `prepare_repo_settings()` before they access the settings themselves. This seems somewhat fragile though, as it is easy to miss and leads to somewhat ugly code patterns at the call sites. Instead, introduce a new function that encapsulates this logic for us. This also allows us to change how exactly the lazy initialization works in the future, e.g. by only partially initializing values as requested by the caller. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Sep 12, 2024 at 13:30 UTC 11dbb4ace3ac428574fadf6f7895f56aba9dca81
9 files changed +23 -13
builtin/rev-parse.c
+3 -1
@@ -19,6 +19,7 @@
19 #include "path.h"
20 #include "diff.h"
21 #include "read-cache-ll.h"
22 +#include "repo-settings.h"
23 #include "repository.h"
24 #include "revision.h"
25 #include "setup.h"
@@ -899,7 +900,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
900 }
901 if (opt_with_value(arg, "--abbrev-ref", &arg)) {
902 abbrev_ref = 1;
902 - abbrev_ref_strict = warn_ambiguous_refs;
903 + abbrev_ref_strict =
904 + repo_settings_get_warn_ambiguous_refs(the_repository);
905 if (arg) {
906 if (!strcmp(arg, "strict"))
907 abbrev_ref_strict = 1;
config.c
-5
@@ -1447,11 +1447,6 @@ static int git_default_core_config(const char *var, const char *value,
1447 return 0;
1448 }
1449
1450 - if (!strcmp(var, "core.warnambiguousrefs")) {
1451 - warn_ambiguous_refs = git_config_bool(var, value);
1452 - return 0;
1453 - }
1454 -
1450 if (!strcmp(var, "core.abbrev")) {
1451 if (!value)
1452 return config_error_nonbool(var);
environment.c
-1
@@ -35,7 +35,6 @@ int minimum_abbrev = 4, default_abbrev = -1;
35 int ignore_case;
36 int assume_unchanged;
37 int is_bare_repository_cfg = -1; /* unspecified */
38 -int warn_ambiguous_refs = 1;
38 int warn_on_object_refname_ambiguity = 1;
39 int repository_format_precious_objects;
40 char *git_commit_encoding;
environment.h
-1
@@ -156,7 +156,6 @@ extern int has_symlinks;
156 extern int minimum_abbrev, default_abbrev;
157 extern int ignore_case;
158 extern int assume_unchanged;
159 -extern int warn_ambiguous_refs;
159 extern int warn_on_object_refname_ambiguity;
160 extern char *apply_default_whitespace;
161 extern char *apply_default_ignorewhitespace;
object-name.c
+3 -2
@@ -20,6 +20,7 @@
20 #include "pretty.h"
21 #include "object-store-ll.h"
22 #include "read-cache-ll.h"
23 +#include "repo-settings.h"
24 #include "repository.h"
25 #include "setup.h"
26 #include "midx.h"
@@ -959,7 +960,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,
960 int fatal = !(flags & GET_OID_QUIETLY);
961
962 if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) {
962 - if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) {
963 + if (repo_settings_get_warn_ambiguous_refs(r) && warn_on_object_refname_ambiguity) {
964 refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0);
965 if (refs_found > 0) {
966 warning(warn_msg, len, str);
@@ -1020,7 +1021,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len,
1021 if (!refs_found)
1022 return -1;
1023
1023 - if (warn_ambiguous_refs && !(flags & GET_OID_QUIETLY) &&
1024 + if (repo_settings_get_warn_ambiguous_refs(r) && !(flags & GET_OID_QUIETLY) &&
1025 (refs_found > 1 ||
1026 !get_short_oid(r, str, len, &tmp_oid, GET_OID_QUIETLY)))
1027 warning(warn_msg, len, str);
ref-filter.c
+2 -1
@@ -13,6 +13,7 @@
13 #include "object-name.h"
14 #include "object-store-ll.h"
15 #include "oid-array.h"
16 +#include "repo-settings.h"
17 #include "repository.h"
18 #include "commit.h"
19 #include "mailmap.h"
@@ -2160,7 +2161,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname)
2161 if (atom->option == R_SHORT)
2162 return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository),
2163 refname,
2163 - warn_ambiguous_refs);
2164 + repo_settings_get_warn_ambiguous_refs(the_repository));
2165 else if (atom->option == R_LSTRIP)
2166 return lstrip_ref_components(refname, atom->lstrip);
2167 else if (atom->option == R_RSTRIP)
refs.c
+2 -2
@@ -730,7 +730,7 @@ int expand_ref(struct repository *repo, const char *str, int len,
730 if (r) {
731 if (!refs_found++)
732 *ref = xstrdup(r);
733 - if (!warn_ambiguous_refs)
733 + if (!repo_settings_get_warn_ambiguous_refs(repo))
734 break;
735 } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
736 warning(_("ignoring dangling symref %s"), fullref.buf);
@@ -775,7 +775,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len,
775 if (oid)
776 oidcpy(oid, &hash);
777 }
778 - if (!warn_ambiguous_refs)
778 + if (!repo_settings_get_warn_ambiguous_refs(r))
779 break;
780 }
781 strbuf_release(&path);
repo-settings.c
+9
@@ -140,3 +140,12 @@ enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *re
140
141 return LOG_REFS_UNSET;
142 }
143 +
144 +int repo_settings_get_warn_ambiguous_refs(struct repository *repo)
145 +{
146 + prepare_repo_settings(repo);
147 + if (repo->settings.warn_ambiguous_refs < 0)
148 + repo_cfg_bool(repo, "core.warnambiguousrefs",
149 + &repo->settings.warn_ambiguous_refs, 1);
150 + return repo->settings.warn_ambiguous_refs;
151 +}
repo-settings.h
+4
@@ -56,16 +56,20 @@ struct repo_settings {
56 enum fetch_negotiation_setting fetch_negotiation_algorithm;
57
58 int core_multi_pack_index;
59 + int warn_ambiguous_refs; /* lazily loaded via accessor */
60 };
61 #define REPO_SETTINGS_INIT { \
62 .index_version = -1, \
63 .core_untracked_cache = UNTRACKED_CACHE_KEEP, \
64 .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \
65 + .warn_ambiguous_refs = -1, \
66 }
67
68 void prepare_repo_settings(struct repository *r);
69
70 /* Read the value for "core.logAllRefUpdates". */
71 enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);
72 +/* Read the value for "core.warnAmbiguousRefs". */
73 +int repo_settings_get_warn_ambiguous_refs(struct repository *repo);
74
75 #endif /* REPO_SETTINGS_H */