From fae2f08a6cd60a7b485012f6ee4344bf847d580e Mon Sep 17 00:00:00 2001 From: Olamide Caleb Bello Date: Tue, 9 Dec 2025 15:52:16 +0000 Subject: [PATCH 1/2] environment: move "core.attributesfile" into repo-setting When handling multiple repositories within the same process, relying on global state for accessing the "core.attributesfile" configuration can lead to incorrect values being used. It also makes it harder to isolate repositories and hinders the libification of git. Move the "core.attributesfile" configuration into the `struct repo_settings` instead of relying on the global state. Add a new function `repo_settings_get_attributesfile_path()` to retrieve this setting in a repository-scoped manner Reported-by: Ayush Chandekar Mentored-by: Christian Couder Mentored-by: Usman Akinyemi Signed-off-by: Olamide Caleb Bello --- attr.c | 8 -------- attr.h | 3 --- environment.c | 6 ------ environment.h | 1 - repo-settings.c | 9 +++++++++ repo-settings.h | 8 ++++++++ 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/attr.c b/attr.c index 4999b7e09d..e746ef170b 100644 --- a/attr.c +++ b/attr.c @@ -879,14 +879,6 @@ const char *git_attr_system_file(void) return system_wide; } -const char *git_attr_global_file(void) -{ - if (!git_attributes_file) - git_attributes_file = xdg_config_home("attributes"); - - return git_attributes_file; -} - int git_attr_system_is_enabled(void) { return !git_env_bool("GIT_ATTR_NOSYSTEM", 0); diff --git a/attr.h b/attr.h index a04a521092..956ce6ba62 100644 --- a/attr.h +++ b/attr.h @@ -232,9 +232,6 @@ void attr_start(void); /* Return the system gitattributes file. */ const char *git_attr_system_file(void); -/* Return the global gitattributes file, if any. */ -const char *git_attr_global_file(void); - /* Return whether the system gitattributes file is enabled and should be used. */ int git_attr_system_is_enabled(void); diff --git a/environment.c b/environment.c index a770b5921d..ed7d8f42d9 100644 --- a/environment.c +++ b/environment.c @@ -53,7 +53,6 @@ char *git_commit_encoding; char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; -char *git_attributes_file; int zlib_compression_level = Z_BEST_SPEED; int pack_compression_level = Z_DEFAULT_COMPRESSION; int fsync_object_files = -1; @@ -363,11 +362,6 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.attributesfile")) { - FREE_AND_NULL(git_attributes_file); - return git_config_pathname(&git_attributes_file, var, value); - } - if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; diff --git a/environment.h b/environment.h index 51898c99cd..3512a7072e 100644 --- a/environment.h +++ b/environment.h @@ -152,7 +152,6 @@ extern int assume_unchanged; extern int warn_on_object_refname_ambiguity; extern char *apply_default_whitespace; extern char *apply_default_ignorewhitespace; -extern char *git_attributes_file; extern int zlib_compression_level; extern int pack_compression_level; extern unsigned long pack_size_limit_cfg; diff --git a/repo-settings.c b/repo-settings.c index 195c24e9c0..d665c2a758 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -5,6 +5,7 @@ #include "midx.h" #include "pack-objects.h" #include "setup.h" +#include "path.h" static void repo_cfg_bool(struct repository *r, const char *key, int *dest, int def) @@ -158,6 +159,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); + FREE_AND_NULL(r->settings.git_attributes_file); r->settings = empty; } @@ -230,3 +232,10 @@ void repo_settings_reset_shared_repository(struct repository *repo) { repo->settings.shared_repository_initialized = 0; } +const char *repo_settings_get_attributesfile_path(struct repository *repo) { + if (!repo->settings.git_attributes_file) { + if(repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.git_attributes_file)) + repo->settings.git_attributes_file = xdg_config_home("attributes"); + } + return repo->settings.git_attributes_file; +} diff --git a/repo-settings.h b/repo-settings.h index d477885561..438c5ce583 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -68,6 +68,7 @@ struct repo_settings { unsigned long big_file_threshold; char *hooks_path; + char *git_attributes_file; }; #define REPO_SETTINGS_INIT { \ .shared_repository = -1, \ @@ -99,4 +100,11 @@ 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); +/* + * Read the value for "core.attributesfile". + * Defaults to xdg_config_home("attributes") if the core.attributes file + * isn't available. + */ +const char *repo_settings_get_attributesfile_path(struct repository *repo); + #endif /* REPO_SETTINGS_H */ -- GitLab From bda9057b799ea81926ed81b8654423ec86155bb9 Mon Sep 17 00:00:00 2001 From: Olamide Caleb Bello Date: Tue, 9 Dec 2025 16:07:50 +0000 Subject: [PATCH 2/2] attr: use `repo_settings_get_attributesfile_path()` and update callers The functions `bootstrap_attr_stack()` and `git_attr_val_system()` retrieve the "core.attributes" file via `git_attr_global_file()` which reads from global state `git_attributes_file`. Update the related functions to retrieve "core.attributesfile" via the new accessor function `repo_settings_get_attributesfile_path()` This improves multi-repository behaviour and aligns with the goal of libifying of Git. Signed-off-by: Olamide Caleb Bello --- attr.c | 6 ++++-- builtin/var.c | 2 +- repo-settings.c | 2 +- repo-settings.h | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/attr.c b/attr.c index e746ef170b..399bf3a35a 100644 --- a/attr.c +++ b/attr.c @@ -904,6 +904,7 @@ static void bootstrap_attr_stack(struct index_state *istate, { struct attr_stack *e; unsigned flags = READ_ATTR_MACRO_OK; + const char *attributes_file_path; if (*stack) return; @@ -919,8 +920,9 @@ static void bootstrap_attr_stack(struct index_state *istate, } /* home directory */ - if (git_attr_global_file()) { - e = read_attr_from_file(git_attr_global_file(), flags); + attributes_file_path = repo_settings_get_attributesfile_path(istate->repo); + if (attributes_file_path) { + e = read_attr_from_file(attributes_file_path, flags); push_stack(stack, e, NULL, 0); } diff --git a/builtin/var.c b/builtin/var.c index cc3a43cde2..fd577f2930 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -72,7 +72,7 @@ static char *git_attr_val_system(int ident_flag UNUSED) static char *git_attr_val_global(int ident_flag UNUSED) { - char *file = xstrdup_or_null(git_attr_global_file()); + char *file = xstrdup_or_null(repo_settings_get_attributesfile_path(the_repository)); if (file) { normalize_path_copy(file, file); return file; diff --git a/repo-settings.c b/repo-settings.c index d665c2a758..d89d7893d4 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -234,7 +234,7 @@ void repo_settings_reset_shared_repository(struct repository *repo) } const char *repo_settings_get_attributesfile_path(struct repository *repo) { if (!repo->settings.git_attributes_file) { - if(repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.git_attributes_file)) + if (repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.git_attributes_file)) repo->settings.git_attributes_file = xdg_config_home("attributes"); } return repo->settings.git_attributes_file; diff --git a/repo-settings.h b/repo-settings.h index 438c5ce583..362f355267 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -102,7 +102,7 @@ void repo_settings_reset_shared_repository(struct repository *repo); /* * Read the value for "core.attributesfile". - * Defaults to xdg_config_home("attributes") if the core.attributes file + * Defaults to xdg_config_home("attributes") if the core.attributesfile * isn't available. */ const char *repo_settings_get_attributesfile_path(struct repository *repo); -- GitLab