]> git.ipfire.org Git - thirdparty/git.git/commitdiff
environment: move access to "core.hooksPath" into repo settings
authorPatrick Steinhardt <ps@pks.im>
Fri, 7 Feb 2025 11:03:39 +0000 (12:03 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 28 Feb 2025 21:54:11 +0000 (13:54 -0800)
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 <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
config.c
environment.c
environment.h
path.c
path.h
repo-settings.c
repo-settings.h

index 50f2d17b39944626172953475a07a56a9d618740..d932d4b1347d13fd18e96428e08f0bb62eb5a273 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1436,11 +1436,6 @@ static int git_default_core_config(const char *var, const char *value,
                return git_config_pathname(&git_attributes_file, var, value);
        }
 
-       if (!strcmp(var, "core.hookspath")) {
-               FREE_AND_NULL(git_hooks_path);
-               return git_config_pathname(&git_hooks_path, var, value);
-       }
-
        if (!strcmp(var, "core.bare")) {
                is_bare_repository_cfg = git_config_bool(var, value);
                return 0;
index 8389a272700eac7e07710b6899eb045c7df4f69a..39755873ee727d60365e5ca95284f53f38d73d96 100644 (file)
@@ -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;
index 2f43340f0b553a3b74b692c4c8a3836cf477506a..66989afbacd1f4e88f29f88c3c430f62fedb83a3 100644 (file)
@@ -160,7 +160,6 @@ extern int warn_on_object_refname_ambiguity;
 extern char *apply_default_whitespace;
 extern char *apply_default_ignorewhitespace;
 extern char *git_attributes_file;
-extern char *git_hooks_path;
 extern int zlib_compression_level;
 extern int pack_compression_level;
 extern size_t packed_git_window_size;
diff --git a/path.c b/path.c
index a42f72800db6737cfa7356482d0c9f1b0ba23603..e81ebd3b5cfdca30c4c4ffd18ff1275da3d4f9da 100644 (file)
--- a/path.c
+++ b/path.c
@@ -387,10 +387,11 @@ void report_linked_checkout_garbage(struct repository *r)
        strbuf_release(&sb);
 }
 
-static void adjust_git_path(const struct repository *repo,
+static void adjust_git_path(struct repository *repo,
                            struct strbuf *buf, int git_dir_len)
 {
        const char *base = buf->buf + git_dir_len;
+
        if (is_dir_file(base, "info", "grafts"))
                strbuf_splice(buf, 0, buf->len,
                              repo->graft_file, strlen(repo->graft_file));
@@ -399,8 +400,8 @@ static void adjust_git_path(const struct repository *repo,
                              repo->index_file, strlen(repo->index_file));
        else if (dir_prefix(base, "objects"))
                replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
-       else if (git_hooks_path && dir_prefix(base, "hooks"))
-               replace_dir(buf, git_dir_len + 5, git_hooks_path);
+       else if (repo_settings_get_hooks_path(repo) && dir_prefix(base, "hooks"))
+               replace_dir(buf, git_dir_len + 5, repo_settings_get_hooks_path(repo));
        else if (repo->different_commondir)
                update_common_dir(buf, git_dir_len, repo->commondir);
 }
@@ -417,7 +418,7 @@ static void strbuf_worktree_gitdir(struct strbuf *buf,
                repo_common_path_append(repo, buf, "worktrees/%s", wt->id);
 }
 
-static void repo_git_pathv(const struct repository *repo,
+static void repo_git_pathv(struct repository *repo,
                           const struct worktree *wt, struct strbuf *buf,
                           const char *fmt, va_list args)
 {
@@ -432,7 +433,7 @@ static void repo_git_pathv(const struct repository *repo,
        strbuf_cleanup_path(buf);
 }
 
-char *repo_git_path(const struct repository *repo,
+char *repo_git_path(struct repository *repo,
                    const char *fmt, ...)
 {
        struct strbuf path = STRBUF_INIT;
@@ -443,7 +444,7 @@ char *repo_git_path(const struct repository *repo,
        return strbuf_detach(&path, NULL);
 }
 
-const char *repo_git_path_append(const struct repository *repo,
+const char *repo_git_path_append(struct repository *repo,
                                 struct strbuf *sb,
                                 const char *fmt, ...)
 {
@@ -454,7 +455,7 @@ const char *repo_git_path_append(const struct repository *repo,
        return sb->buf;
 }
 
-const char *repo_git_path_replace(const struct repository *repo,
+const char *repo_git_path_replace(struct repository *repo,
                                  struct strbuf *sb,
                                  const char *fmt, ...)
 {
diff --git a/path.h b/path.h
index f28d5a7ca9525c5325ab438e386e974733c19c8c..373404dd9d2a5f50370441ebf7e29a1fa7ffc34a 100644 (file)
--- a/path.h
+++ b/path.h
@@ -52,14 +52,14 @@ const char *repo_common_path_replace(const struct repository *repo,
  * For an exhaustive list of the adjustments made look at `common_list` and
  * `adjust_git_path` in path.c.
  */
-char *repo_git_path(const struct repository *repo,
+char *repo_git_path(struct repository *repo,
                    const char *fmt, ...)
        __attribute__((format (printf, 2, 3)));
-const char *repo_git_path_append(const struct repository *repo,
+const char *repo_git_path_append(struct repository *repo,
                                 struct strbuf *sb,
                                 const char *fmt, ...)
        __attribute__((format (printf, 3, 4)));
-const char *repo_git_path_replace(const struct repository *repo,
+const char *repo_git_path_replace(struct repository *repo,
                                  struct strbuf *sb,
                                  const char *fmt, ...)
        __attribute__((format (printf, 3, 4)));
index 719cd7c85c7be663b091edfb719c3edbb22e2a28..876d5275816b84679fb669dc484b220f9357474c 100644 (file)
@@ -146,6 +146,7 @@ void repo_settings_clear(struct repository *r)
 {
        struct repo_settings empty = REPO_SETTINGS_INIT;
        FREE_AND_NULL(r->settings.fsmonitor);
+       FREE_AND_NULL(r->settings.hooks_path);
        r->settings = empty;
 }
 
@@ -173,3 +174,10 @@ int repo_settings_get_warn_ambiguous_refs(struct repository *repo)
                              &repo->settings.warn_ambiguous_refs, 1);
        return repo->settings.warn_ambiguous_refs;
 }
+
+const char *repo_settings_get_hooks_path(struct repository *repo)
+{
+       if (!repo->settings.hooks_path)
+               repo_config_get_pathname(repo, "core.hookspath", &repo->settings.hooks_path);
+       return repo->settings.hooks_path;
+}
index c4f7e3bd8a8fe8b78907380c8afacb8a65b062bf..0cef970443be80ce7b784a9afe16eafa558b14c4 100644 (file)
@@ -61,6 +61,8 @@ struct repo_settings {
        size_t delta_base_cache_limit;
        size_t packed_git_window_size;
        size_t packed_git_limit;
+
+       char *hooks_path;
 };
 #define REPO_SETTINGS_INIT { \
        .index_version = -1, \
@@ -79,5 +81,7 @@ void repo_settings_clear(struct repository *r);
 enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);
 /* Read the value for "core.warnAmbiguousRefs". */
 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);
 
 #endif /* REPO_SETTINGS_H */