From 6f3fbed8eda577703426d77dacc71ce0ba46634e Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Feb 2025 12:03:39 +0100 Subject: environment: move access to "core.hooksPath" into repo settings The "core.hooksPath" setting is stored in a global variable and populated via the `git_default_core_config`. This may cause issues in the case where one is handling multiple different repositories in a single process with different values for that config key, as we may or may not see the correct value in that case. Furthermore, global state blocks our path towards libification. Refactor the code so that we instead store the value in `struct repo_settings`. The value is computed as-needed and cached. The result should be functionally the same as there aren't ever any code paths where we'd execute hooks outside the context of a repository. Note that this requires us to change the passed-in repository in the `repo_git_path()` family of functions to be non-constant, as we call `adjust_git_path()` there. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- environment.c | 1 - 1 file changed, 1 deletion(-) (limited to 'environment.c') diff --git a/environment.c b/environment.c index 8389a27270..39755873ee 100644 --- a/environment.c +++ b/environment.c @@ -42,7 +42,6 @@ char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; char *git_attributes_file; -char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int pack_compression_level = Z_DEFAULT_COMPRESSION; int fsync_object_files = -1; -- cgit v1.3 From f1ce861c34bffbc02998173016b0bca0f6d9f6c4 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 7 Feb 2025 12:03:40 +0100 Subject: environment: move access to "core.sharedRepository" into repo settings Similar as with the preceding commit, we track "core.sharedRepository" via a pair of global variables. Move them into `struct repo_settings` so that we can instead track them per-repository. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/init-db.c | 8 ++++---- builtin/log.c | 6 +++--- environment.c | 26 -------------------------- environment.h | 10 ---------- path.c | 10 +++++----- repo-settings.c | 26 ++++++++++++++++++++++++++ repo-settings.h | 9 +++++++++ setup.c | 21 +++++++++++---------- 8 files changed, 58 insertions(+), 58 deletions(-) (limited to 'environment.c') diff --git a/builtin/init-db.c b/builtin/init-db.c index 096f96b9c4..196dccdd77 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -132,8 +132,8 @@ int cmd_init_db(int argc, * and we know shared_repository should always be 0; * but just in case we play safe. */ - saved = get_shared_repository(); - set_shared_repository(0); + saved = repo_settings_get_shared_repository(the_repository); + repo_settings_set_shared_repository(the_repository, 0); switch (safe_create_leading_directories_const(argv[0])) { case SCLD_OK: case SCLD_PERMS: @@ -145,7 +145,7 @@ int cmd_init_db(int argc, die_errno(_("cannot mkdir %s"), argv[0]); break; } - set_shared_repository(saved); + repo_settings_set_shared_repository(the_repository, saved); if (mkdir(argv[0], 0777) < 0) die_errno(_("cannot mkdir %s"), argv[0]); mkdir_tried = 1; @@ -175,7 +175,7 @@ int cmd_init_db(int argc, } if (init_shared_repository != -1) - set_shared_repository(init_shared_repository); + repo_settings_set_shared_repository(the_repository, init_shared_repository); /* * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR diff --git a/builtin/log.c b/builtin/log.c index e41f88945e..04a6ef97bc 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -2309,8 +2309,8 @@ int cmd_format_patch(int argc, * We consider as 'outside of gitdir', therefore avoid * applying adjust_shared_perm in s-c-l-d. */ - saved = get_shared_repository(); - set_shared_repository(0); + saved = repo_settings_get_shared_repository(the_repository); + repo_settings_set_shared_repository(the_repository, 0); switch (safe_create_leading_directories_const(output_directory)) { case SCLD_OK: case SCLD_EXISTS: @@ -2319,7 +2319,7 @@ int cmd_format_patch(int argc, die(_("could not create leading directories " "of '%s'"), output_directory); } - set_shared_repository(saved); + repo_settings_set_shared_repository(the_repository, saved); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) die_errno(_("could not create directory '%s'"), output_directory); diff --git a/environment.c b/environment.c index 39755873ee..c79acc69e7 100644 --- a/environment.c +++ b/environment.c @@ -206,32 +206,6 @@ const char *get_commit_output_encoding(void) return git_commit_encoding ? git_commit_encoding : "UTF-8"; } -static int the_shared_repository = PERM_UMASK; -static int need_shared_repository_from_config = 1; - -void set_shared_repository(int value) -{ - the_shared_repository = value; - need_shared_repository_from_config = 0; -} - -int get_shared_repository(void) -{ - if (need_shared_repository_from_config) { - const char *var = "core.sharedrepository"; - const char *value; - if (!git_config_get_value(var, &value)) - the_shared_repository = git_config_perm(var, value); - need_shared_repository_from_config = 0; - } - return the_shared_repository; -} - -void reset_shared_repository(void) -{ - need_shared_repository_from_config = 1; -} - int use_optional_locks(void) { return git_env_bool(GIT_OPTIONAL_LOCKS_ENVIRONMENT, 1); diff --git a/environment.h b/environment.h index 66989afbac..45e690f203 100644 --- a/environment.h +++ b/environment.h @@ -134,16 +134,6 @@ void setup_git_env(const char *git_dir); */ int have_git_dir(void); -/* - * Accessors for the core.sharedrepository config which lazy-load the value - * from the config (if not already set). The "reset" function can be - * used to unset "set" or cached value, meaning that the value will be loaded - * fresh from the config file on the next call to get_shared_repository(). - */ -void set_shared_repository(int value); -int get_shared_repository(void); -void reset_shared_repository(void); - extern int is_bare_repository_cfg; int is_bare_repository(void); extern char *git_work_tree_cfg; diff --git a/path.c b/path.c index e81ebd3b5c..a2f402baec 100644 --- a/path.c +++ b/path.c @@ -844,17 +844,17 @@ int calc_shared_perm(int mode) { int tweak; - if (get_shared_repository() < 0) - tweak = -get_shared_repository(); + if (repo_settings_get_shared_repository(the_repository) < 0) + tweak = -repo_settings_get_shared_repository(the_repository); else - tweak = get_shared_repository(); + tweak = repo_settings_get_shared_repository(the_repository); if (!(mode & S_IWUSR)) tweak &= ~0222; if (mode & S_IXUSR) /* Copy read bits to execute bits */ tweak |= (tweak & 0444) >> 2; - if (get_shared_repository() < 0) + if (repo_settings_get_shared_repository(the_repository) < 0) mode = (mode & ~0777) | tweak; else mode |= tweak; @@ -867,7 +867,7 @@ int adjust_shared_perm(const char *path) { int old_mode, new_mode; - if (!get_shared_repository()) + if (!repo_settings_get_shared_repository(the_repository)) return 0; if (get_st_mode_bits(path, &old_mode) < 0) return -1; diff --git a/repo-settings.c b/repo-settings.c index 876d527581..67e9cfd2e6 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -4,6 +4,7 @@ #include "repository.h" #include "midx.h" #include "pack-objects.h" +#include "setup.h" static void repo_cfg_bool(struct repository *r, const char *key, int *dest, int def) @@ -181,3 +182,28 @@ const char *repo_settings_get_hooks_path(struct repository *repo) repo_config_get_pathname(repo, "core.hookspath", &repo->settings.hooks_path); return repo->settings.hooks_path; } + +int repo_settings_get_shared_repository(struct repository *repo) +{ + if (!repo->settings.shared_repository_initialized) { + const char *var = "core.sharedrepository"; + const char *value; + if (!repo_config_get_value(repo, var, &value)) + repo->settings.shared_repository = git_config_perm(var, value); + else + repo->settings.shared_repository = PERM_UMASK; + repo->settings.shared_repository_initialized = 1; + } + return repo->settings.shared_repository; +} + +void repo_settings_set_shared_repository(struct repository *repo, int value) +{ + repo->settings.shared_repository = value; + repo->settings.shared_repository_initialized = 1; +} + +void repo_settings_reset_shared_repository(struct repository *repo) +{ + repo->settings.shared_repository_initialized = 0; +} diff --git a/repo-settings.h b/repo-settings.h index 0cef970443..ddc11967e0 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -37,6 +37,9 @@ struct repo_settings { int pack_use_bitmap_boundary_traversal; int pack_use_multi_pack_reuse; + int shared_repository; + int shared_repository_initialized; + /* * Does this repository have core.useReplaceRefs=true (on by * default)? This provides a repository-scoped version of this @@ -65,6 +68,7 @@ struct repo_settings { char *hooks_path; }; #define REPO_SETTINGS_INIT { \ + .shared_repository = -1, \ .index_version = -1, \ .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ @@ -84,4 +88,9 @@ int repo_settings_get_warn_ambiguous_refs(struct repository *repo); /* Read the value for "core.hooksPath". */ const char *repo_settings_get_hooks_path(struct repository *repo); +/* Read, set or reset the value for "core.sharedRepository". */ +int repo_settings_get_shared_repository(struct repository *repo); +void repo_settings_set_shared_repository(struct repository *repo, int value); +void repo_settings_reset_shared_repository(struct repository *repo); + #endif /* REPO_SETTINGS_H */ diff --git a/setup.c b/setup.c index 30889386f7..aa65b93f53 100644 --- a/setup.c +++ b/setup.c @@ -2332,7 +2332,7 @@ static int create_default_files(const char *template_path, */ copy_templates(template_path); git_config_clear(); - reset_shared_repository(); + repo_settings_reset_shared_repository(the_repository); git_config(git_default_config, NULL); reinit = is_reinit(); @@ -2342,7 +2342,8 @@ static int create_default_files(const char *template_path, * values we might have just re-read from the config. */ if (init_shared_repository != -1) - set_shared_repository(init_shared_repository); + repo_settings_set_shared_repository(the_repository, + init_shared_repository); is_bare_repository_cfg = !work_tree; @@ -2350,7 +2351,7 @@ static int create_default_files(const char *template_path, * We would have created the above under user's umask -- under * shared-repository settings, we would need to fix them up. */ - if (get_shared_repository()) { + if (repo_settings_get_shared_repository(the_repository)) { adjust_shared_perm(repo_get_git_dir(the_repository)); } @@ -2597,7 +2598,7 @@ int init_db(const char *git_dir, const char *real_git_dir, initial_branch, flags & INIT_DB_QUIET); create_object_directory(); - if (get_shared_repository()) { + if (repo_settings_get_shared_repository(the_repository)) { char buf[10]; /* We do not spell "group" and such, so that * the configuration can be read by older version @@ -2605,12 +2606,12 @@ int init_db(const char *git_dir, const char *real_git_dir, * and compatibility values for PERM_GROUP and * PERM_EVERYBODY. */ - if (get_shared_repository() < 0) + if (repo_settings_get_shared_repository(the_repository) < 0) /* force to the mode value */ - xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository()); - else if (get_shared_repository() == PERM_GROUP) + xsnprintf(buf, sizeof(buf), "0%o", -repo_settings_get_shared_repository(the_repository)); + else if (repo_settings_get_shared_repository(the_repository) == PERM_GROUP) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP); - else if (get_shared_repository() == PERM_EVERYBODY) + else if (repo_settings_get_shared_repository(the_repository) == PERM_EVERYBODY) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else BUG("invalid value for shared_repository"); @@ -2622,12 +2623,12 @@ int init_db(const char *git_dir, const char *real_git_dir, int len = strlen(git_dir); if (reinit) - printf(get_shared_repository() + printf(repo_settings_get_shared_repository(the_repository) ? _("Reinitialized existing shared Git repository in %s%s\n") : _("Reinitialized existing Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); else - printf(get_shared_repository() + printf(repo_settings_get_shared_repository(the_repository) ? _("Initialized empty shared Git repository in %s%s\n") : _("Initialized empty Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); -- cgit v1.3