environment: stop storing "core.logAllRefUpdates" globally
The value of "core.logAllRefUpdates" is being stored in the global variable `log_all_ref_updates`. This design is somewhat aged nowadays, where it is entirely possible to access multiple repositories in the same process which all have different values for this setting. So using a single global variable to track it is plain wrong. Remove the global variable. Instead, we now provide a new function part of the repo-settings subsystem that parses the value for a specific repository. While that may require us to read the value multiple times, we work around this by reading it once when the ref backends are set up and caching the value there. 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
eafb126456b235c5281e3ae50bfd526552ce12d3
9 files changed
+32
-20
builtin/checkout.c
+2
@@ -951,6 +951,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
951
const char *old_desc, *reflog_msg;
952
if (opts->new_branch) {
953
if (opts->new_orphan_branch) {
954
+ enum log_refs_config log_all_ref_updates =
955
+ repo_settings_get_log_all_ref_updates(the_repository);
956
char *refname;
957
958
refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
config.c
-10
@@ -1452,16 +1452,6 @@ static int git_default_core_config(const char *var, const char *value,
1452
return 0;
1453
}
1454
1455
- if (!strcmp(var, "core.logallrefupdates")) {
1456
- if (value && !strcasecmp(value, "always"))
1457
- log_all_ref_updates = LOG_REFS_ALWAYS;
1458
- else if (git_config_bool(var, value))
1459
- log_all_ref_updates = LOG_REFS_NORMAL;
1460
- else
1461
- log_all_ref_updates = LOG_REFS_NONE;
1462
- return 0;
1463
- }
1464
-
1455
if (!strcmp(var, "core.warnambiguousrefs")) {
1456
warn_ambiguous_refs = git_config_bool(var, value);
1457
return 0;
environment.c
-1
@@ -77,7 +77,6 @@ int sparse_expect_files_outside_of_patterns;
77
int merge_log_config = -1;
78
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
79
unsigned long pack_size_limit_cfg;
80
-enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET;
80
int max_allowed_tree_depth =
81
#ifdef _MSC_VER
82
/*
environment.h
-2
@@ -181,8 +181,6 @@ extern int core_apply_sparse_checkout;
181
extern int core_sparse_checkout_cone;
182
extern int sparse_expect_files_outside_of_patterns;
183
184
-extern enum log_refs_config log_all_ref_updates;
185
-
184
enum rebase_setup_type {
185
AUTOREBASE_NEVER = 0,
186
AUTOREBASE_LOCAL,
refs/files-backend.c
+3
-1
@@ -75,6 +75,7 @@ struct files_ref_store {
75
unsigned int store_flags;
76
77
char *gitcommondir;
78
+ enum log_refs_config log_all_ref_updates;
79
80
struct ref_cache *loose;
81
@@ -107,6 +108,7 @@ static struct ref_store *files_ref_store_init(struct repository *repo,
108
refs->gitcommondir = strbuf_detach(&sb, NULL);
109
refs->packed_ref_store =
110
packed_ref_store_init(repo, refs->gitcommondir, flags);
111
+ refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);
112
113
chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
114
chdir_notify_reparent("files-backend $GIT_COMMONDIR",
@@ -1704,7 +1706,7 @@ static int log_ref_setup(struct files_ref_store *refs,
1706
const char *refname, int force_create,
1707
int *logfd, struct strbuf *err)
1708
{
1707
- enum log_refs_config log_refs_cfg = log_all_ref_updates;
1709
+ enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;
1710
struct strbuf logfile_sb = STRBUF_INIT;
1711
char *logfile;
1712
refs/reftable-backend.c
+7
-5
@@ -52,6 +52,7 @@ struct reftable_ref_store {
52
struct reftable_write_options write_options;
53
54
unsigned int store_flags;
55
+ enum log_refs_config log_all_ref_updates;
56
int err;
57
};
58
@@ -157,21 +158,21 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store,
158
}
159
}
160
160
-static int should_write_log(struct ref_store *refs, const char *refname)
161
+static int should_write_log(struct reftable_ref_store *refs, const char *refname)
162
{
162
- enum log_refs_config log_refs_cfg = log_all_ref_updates;
163
+ enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;
164
if (log_refs_cfg == LOG_REFS_UNSET)
165
log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL;
166
167
switch (log_refs_cfg) {
168
case LOG_REFS_NONE:
168
- return refs_reflog_exists(refs, refname);
169
+ return refs_reflog_exists(&refs->base, refname);
170
case LOG_REFS_ALWAYS:
171
return 1;
172
case LOG_REFS_NORMAL:
173
if (should_autocreate_reflog(log_refs_cfg, refname))
174
return 1;
174
- return refs_reflog_exists(refs, refname);
175
+ return refs_reflog_exists(&refs->base, refname);
176
default:
177
BUG("unhandled core.logAllRefUpdates value %d", log_refs_cfg);
178
}
@@ -278,6 +279,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
279
base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable);
280
strmap_init(&refs->worktree_stacks);
281
refs->store_flags = store_flags;
282
+ refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);
283
284
refs->write_options.hash_id = repo->hash_algo->format_id;
285
refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask);
@@ -1220,7 +1222,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
1222
} else if (!(u->flags & REF_SKIP_CREATE_REFLOG) &&
1223
(u->flags & REF_HAVE_NEW) &&
1224
(u->flags & REF_FORCE_CREATE_REFLOG ||
1223
- should_write_log(&arg->refs->base, u->refname))) {
1225
+ should_write_log(arg->refs, u->refname))) {
1226
struct reftable_log_record *log;
1227
int create_reflog = 1;
1228
repo-settings.c
+16
@@ -124,3 +124,19 @@ void prepare_repo_settings(struct repository *r)
124
*/
125
r->settings.command_requires_full_index = 1;
126
}
127
+
128
+enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo)
129
+{
130
+ const char *value;
131
+
132
+ if (!repo_config_get_string_tmp(repo, "core.logallrefupdates", &value)) {
133
+ if (value && !strcasecmp(value, "always"))
134
+ return LOG_REFS_ALWAYS;
135
+ else if (git_config_bool("core.logallrefupdates", value))
136
+ return LOG_REFS_NORMAL;
137
+ else
138
+ return LOG_REFS_NONE;
139
+ }
140
+
141
+ return LOG_REFS_UNSET;
142
+}
repo-settings.h
+3
@@ -65,4 +65,7 @@ struct repo_settings {
65
66
void prepare_repo_settings(struct repository *r);
67
68
+/* Read the value for "core.logAllRefUpdates". */
69
+enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);
70
+
71
#endif /* REPO_SETTINGS_H */
setup.c
+1
-1
@@ -2354,7 +2354,7 @@ static int create_default_files(const char *template_path,
2354
else {
2355
git_config_set("core.bare", "false");
2356
/* allow template config file to override the default */
2357
- if (log_all_ref_updates == LOG_REFS_UNSET)
2357
+ if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET)
2358
git_config_set("core.logallrefupdates", "true");
2359
if (needs_work_tree_config(original_git_dir, work_tree))
2360
git_config_set("core.worktree", work_tree);