git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
@ 2025-12-18  8:30 Olamide Caleb Bello
  2025-12-18 17:31 ` Bello Olamide
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Olamide Caleb Bello @ 2025-12-18  8:30 UTC (permalink / raw)
  To: git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

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.
The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
retrieve "core.attributesFile" via `git_attr_global_file()`
which reads from global state `git_attributes_file`.

Move the "core.attributesFile" configuration into the
`struct repo_settings` instead of relying on the global state.
A new function `repo_settings_get_attributesfile_path()` is added
and used to retrieve this setting in a repository-scoped manner.
The functions to retrieve "core.attributesFile" are replaced with
the new accessor function `repo_settings_get_attributesfile_path()`
This improves multi-repository behaviour and aligns with the goal of
libifying of Git.

Note that in `bootstrap_attr_stack()`, the `index_state` is used only
if it exists, else we default to `the_repository`.

Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
---
The link to the GitHub CI is provided below
https://github.com/cloobTech/git/actions/runs/20284228144

 attr.c          | 20 +++++++++-----------
 attr.h          |  3 ---
 builtin/var.c   |  2 +-
 environment.c   |  6 ------
 environment.h   |  1 -
 repo-settings.c | 10 ++++++++++
 repo-settings.h |  8 ++++++++
 7 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/attr.c b/attr.c
index 4999b7e09d..9e51f8e70b 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);
@@ -912,6 +904,8 @@ static void bootstrap_attr_stack(struct index_state *istate,
 {
 	struct attr_stack *e;
 	unsigned flags = READ_ATTR_MACRO_OK;
+	const char *attributes_file_path;
+	struct repository *repo;
 
 	if (*stack)
 		return;
@@ -926,9 +920,13 @@ static void bootstrap_attr_stack(struct index_state *istate,
 		push_stack(stack, e, NULL, 0);
 	}
 
-	/* home directory */
-	if (git_attr_global_file()) {
-		e = read_attr_from_file(git_attr_global_file(), flags);
+	if (istate && istate->repo)
+		repo = istate->repo;
+	else
+		repo = the_repository;
+	attributes_file_path = repo_settings_get_attributesfile_path(repo);
+	if (attributes_file_path) {
+		e = read_attr_from_file(attributes_file_path, flags);
 		push_stack(stack, e, NULL, 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/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/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..396cf79f20 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,11 @@ 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..362f355267 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.attributesfile
+ * isn't available.
+ */
+const char *repo_settings_get_attributesfile_path(struct repository *repo);
+
 #endif /* REPO_SETTINGS_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
  2025-12-18  8:30 [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting Olamide Caleb Bello
@ 2025-12-18 17:31 ` Bello Olamide
  2026-01-02  8:01 ` Bello Olamide
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2025-12-18 17:31 UTC (permalink / raw)
  To: git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

On Thu, 18 Dec 2025 at 09:30, Olamide Caleb Bello <belkid98@gmail.com> wrote:
>
> 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.
> The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> retrieve "core.attributesFile" via `git_attr_global_file()`
> which reads from global state `git_attributes_file`.
>
> Move the "core.attributesFile" configuration into the
> `struct repo_settings` instead of relying on the global state.
> A new function `repo_settings_get_attributesfile_path()` is added
> and used to retrieve this setting in a repository-scoped manner.
> The functions to retrieve "core.attributesFile" are replaced with
> the new accessor function `repo_settings_get_attributesfile_path()`
> This improves multi-repository behaviour and aligns with the goal of
> libifying of Git.
>
> Note that in `bootstrap_attr_stack()`, the `index_state` is used only
> if it exists, else we default to `the_repository`.
>
> Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
> ---
> The link to the GitHub CI is provided below
> https://github.com/cloobTech/git/actions/runs/20284228144

The link to Ayush's patches, which this patch is based on, is provided in
[1].
The 'git_attributes_file' member of `struct repository` is now
accessed via the `struct index_state`,
istate->repo, as most of the callers in the attributes subsystem
already use the `index_state`,
rather than through the `struct repository *repo` as done in [1] which
only knows its primary index.
This ensures that the index actually owns the attributes as pointed
out by Junio in the threads.

[1]. https://lore.kernel.org/git/20250309153321.254844-1-ayu.chandekar@gmail.com/

>
>  attr.c          | 20 +++++++++-----------
>  attr.h          |  3 ---
>  builtin/var.c   |  2 +-
>  environment.c   |  6 ------
>  environment.h   |  1 -
>  repo-settings.c | 10 ++++++++++
>  repo-settings.h |  8 ++++++++
>  7 files changed, 28 insertions(+), 22 deletions(-)
>
> diff --git a/attr.c b/attr.c
> index 4999b7e09d..9e51f8e70b 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);
> @@ -912,6 +904,8 @@ static void bootstrap_attr_stack(struct index_state *istate,
>  {
>         struct attr_stack *e;
>         unsigned flags = READ_ATTR_MACRO_OK;
> +       const char *attributes_file_path;
> +       struct repository *repo;
>
>         if (*stack)
>                 return;
> @@ -926,9 +920,13 @@ static void bootstrap_attr_stack(struct index_state *istate,
>                 push_stack(stack, e, NULL, 0);
>         }
>
> -       /* home directory */
> -       if (git_attr_global_file()) {
> -               e = read_attr_from_file(git_attr_global_file(), flags);
> +       if (istate && istate->repo)
> +               repo = istate->repo;
> +       else
> +               repo = the_repository;
> +       attributes_file_path = repo_settings_get_attributesfile_path(repo);
> +       if (attributes_file_path) {
> +               e = read_attr_from_file(attributes_file_path, flags);
>                 push_stack(stack, e, NULL, 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/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/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..396cf79f20 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,11 @@ 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..362f355267 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.attributesfile
> + * isn't available.
> + */
> +const char *repo_settings_get_attributesfile_path(struct repository *repo);
> +
>  #endif /* REPO_SETTINGS_H */
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
  2025-12-18  8:30 [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting Olamide Caleb Bello
  2025-12-18 17:31 ` Bello Olamide
@ 2026-01-02  8:01 ` Bello Olamide
  2026-01-02  8:49   ` Karthik Nayak
  2026-01-02  8:48 ` Karthik Nayak
  2026-01-02 16:32 ` [Outreachy PATCH v2] " Olamide Caleb Bello
  3 siblings, 1 reply; 21+ messages in thread
From: Bello Olamide @ 2026-01-02  8:01 UTC (permalink / raw)
  To: git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

On Thu, 18 Dec 2025 at 09:30, Olamide Caleb Bello <belkid98@gmail.com> wrote:
>
> 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.
> The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> retrieve "core.attributesFile" via `git_attr_global_file()`
> which reads from global state `git_attributes_file`.
>
> Move the "core.attributesFile" configuration into the
> `struct repo_settings` instead of relying on the global state.
> A new function `repo_settings_get_attributesfile_path()` is added
> and used to retrieve this setting in a repository-scoped manner.
> The functions to retrieve "core.attributesFile" are replaced with
> the new accessor function `repo_settings_get_attributesfile_path()`
> This improves multi-repository behaviour and aligns with the goal of
> libifying of Git.
>
> Note that in `bootstrap_attr_stack()`, the `index_state` is used only
> if it exists, else we default to `the_repository`.
>
> Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>

Hello.
Please I am replying to this as no reviews have been done on this patch.
Thanks
[...]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
  2025-12-18  8:30 [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting Olamide Caleb Bello
  2025-12-18 17:31 ` Bello Olamide
  2026-01-02  8:01 ` Bello Olamide
@ 2026-01-02  8:48 ` Karthik Nayak
  2026-01-02 11:26   ` Bello Olamide
  2026-01-02 16:32 ` [Outreachy PATCH v2] " Olamide Caleb Bello
  3 siblings, 1 reply; 21+ messages in thread
From: Karthik Nayak @ 2026-01-02  8:48 UTC (permalink / raw)
  To: Olamide Caleb Bello, git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

[-- Attachment #1: Type: text/plain, Size: 3024 bytes --]

Olamide Caleb Bello <belkid98@gmail.com> writes:

> 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.
> The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> retrieve "core.attributesFile" via `git_attr_global_file()`
> which reads from global state `git_attributes_file`.
>
> Move the "core.attributesFile" configuration into the
> `struct repo_settings` instead of relying on the global state.
> A new function `repo_settings_get_attributesfile_path()` is added
> and used to retrieve this setting in a repository-scoped manner.
> The functions to retrieve "core.attributesFile" are replaced with
> the new accessor function `repo_settings_get_attributesfile_path()`
> This improves multi-repository behaviour and aligns with the goal of
> libifying of Git.
>
> Note that in `bootstrap_attr_stack()`, the `index_state` is used only
> if it exists, else we default to `the_repository`.
>
> Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
> ---
> The link to the GitHub CI is provided below
> https://github.com/cloobTech/git/actions/runs/20284228144
>
>  attr.c          | 20 +++++++++-----------
>  attr.h          |  3 ---
>  builtin/var.c   |  2 +-
>  environment.c   |  6 ------
>  environment.h   |  1 -
>  repo-settings.c | 10 ++++++++++
>  repo-settings.h |  8 ++++++++
>  7 files changed, 28 insertions(+), 22 deletions(-)

The change is very welcome. Apart from some small comments below, the
patch looks good.

[snip]

> diff --git a/repo-settings.h b/repo-settings.h
> index d477885561..362f355267 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, \

It would make more sense to rename this variable to
`attributes_file_path`, that would better denote what is actually stored
here and syncs better with `repo_settings_get_attributesfile_path`.

> @@ -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.attributesfile
> + * isn't available.

While it is obvious, it would be nice to point out that
`core.attributesfile` is set via config.

> + */
> +const char *repo_settings_get_attributesfile_path(struct repository *repo);
> +
>  #endif /* REPO_SETTINGS_H */
> --
> 2.34.1

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
  2026-01-02  8:01 ` Bello Olamide
@ 2026-01-02  8:49   ` Karthik Nayak
  0 siblings, 0 replies; 21+ messages in thread
From: Karthik Nayak @ 2026-01-02  8:49 UTC (permalink / raw)
  To: Bello Olamide, git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

[-- Attachment #1: Type: text/plain, Size: 1671 bytes --]

Bello Olamide <belkid98@gmail.com> writes:

> On Thu, 18 Dec 2025 at 09:30, Olamide Caleb Bello <belkid98@gmail.com> wrote:
>>
>> 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.
>> The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
>> retrieve "core.attributesFile" via `git_attr_global_file()`
>> which reads from global state `git_attributes_file`.
>>
>> Move the "core.attributesFile" configuration into the
>> `struct repo_settings` instead of relying on the global state.
>> A new function `repo_settings_get_attributesfile_path()` is added
>> and used to retrieve this setting in a repository-scoped manner.
>> The functions to retrieve "core.attributesFile" are replaced with
>> the new accessor function `repo_settings_get_attributesfile_path()`
>> This improves multi-repository behaviour and aligns with the goal of
>> libifying of Git.
>>
>> Note that in `bootstrap_attr_stack()`, the `index_state` is used only
>> if it exists, else we default to `the_repository`.
>>
>> Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
>> Mentored-by: Christian Couder <christian.couder@gmail.com>
>> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
>> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
>
> Hello.
> Please I am replying to this as no reviews have been done on this patch.
> Thanks

Thanks for the bump, I think reviews are slowed down due to holidays.
You should see a uptick henceforth :)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting
  2026-01-02  8:48 ` Karthik Nayak
@ 2026-01-02 11:26   ` Bello Olamide
  0 siblings, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2026-01-02 11:26 UTC (permalink / raw)
  To: Karthik Nayak
  Cc: git, gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

On Fri, 2 Jan 2026 at 09:48, Karthik Nayak <karthik.188@gmail.com> wrote:
>
> Olamide Caleb Bello <belkid98@gmail.com> writes:
>
> > 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.
> > The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> > retrieve "core.attributesFile" via `git_attr_global_file()`
> > which reads from global state `git_attributes_file`.
> >
> > Move the "core.attributesFile" configuration into the
> > `struct repo_settings` instead of relying on the global state.
> > A new function `repo_settings_get_attributesfile_path()` is added
> > and used to retrieve this setting in a repository-scoped manner.
> > The functions to retrieve "core.attributesFile" are replaced with
> > the new accessor function `repo_settings_get_attributesfile_path()`
> > This improves multi-repository behaviour and aligns with the goal of
> > libifying of Git.
> >
> > Note that in `bootstrap_attr_stack()`, the `index_state` is used only
> > if it exists, else we default to `the_repository`.
> >
> > Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
> > Mentored-by: Christian Couder <christian.couder@gmail.com>
> > Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
> > Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
> > ---
> > The link to the GitHub CI is provided below
> > https://github.com/cloobTech/git/actions/runs/20284228144
> >
> >  attr.c          | 20 +++++++++-----------
> >  attr.h          |  3 ---
> >  builtin/var.c   |  2 +-
> >  environment.c   |  6 ------
> >  environment.h   |  1 -
> >  repo-settings.c | 10 ++++++++++
> >  repo-settings.h |  8 ++++++++
> >  7 files changed, 28 insertions(+), 22 deletions(-)
>
> The change is very welcome. Apart from some small comments below, the
> patch looks good.
>
> [snip]
>
> > diff --git a/repo-settings.h b/repo-settings.h
> > index d477885561..362f355267 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, \
>
> It would make more sense to rename this variable to
> `attributes_file_path`, that would better denote what is actually stored
> here and syncs better with `repo_settings_get_attributesfile_path`.
>
> > @@ -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.attributesfile
> > + * isn't available.
>
> While it is obvious, it would be nice to point out that
> `core.attributesfile` is set via config.
>
Thank you for the review Karthik.
I will send an updated version with the changes.

Bello.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2025-12-18  8:30 [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting Olamide Caleb Bello
                   ` (2 preceding siblings ...)
  2026-01-02  8:48 ` Karthik Nayak
@ 2026-01-02 16:32 ` Olamide Caleb Bello
  2026-01-05 11:09   ` Karthik Nayak
  2026-01-05 14:23   ` Phillip Wood
  3 siblings, 2 replies; 21+ messages in thread
From: Olamide Caleb Bello @ 2026-01-02 16:32 UTC (permalink / raw)
  To: git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

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.
The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
retrieve "core.attributesFile" via `git_attr_global_file()`
which reads from global state `git_attributes_file`.

Move the "core.attributesFile" configuration into the
`struct repo_settings` instead of relying on the global state.
A new function `repo_settings_get_attributesfile_path()` is added
and used to retrieve this setting in a repository-scoped manner.
The functions to retrieve "core.attributesFile" are replaced with
the new accessor function `repo_settings_get_attributesfile_path()`
This improves multi-repository behaviour and aligns with the goal of
libifying of Git.

Note that in `bootstrap_attr_stack()`, the `index_state` is used only
if it exists, else we default to `the_repository`.

Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
---
The link to the GitHub CI is provided below
https://github.com/git/git/actions/runs/20661817110

Changes in v2:
--------------
- Renamed the variable in the repo-settings struct to `attributes_file_path`
- Modified the comment section of the accessor function declaration to
  indicate the core.attributesFile is read via repo config.

Range diff vs v1:
-----------------
1:  4975f77cde ! 1:  fc1dbec892 environment: move "core.attributesfile" into repo-setting
    @@ Commit message
         Note that in `bootstrap_attr_stack()`, the `index_state` is used only
         if it exists, else we default to `the_repository`.
     
    -    Reported-by: Ayush Chandekar <ayu.chandekar@gmail.com>
    +    Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
         Mentored-by: Christian Couder <christian.couder@gmail.com>
         Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
         Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
    @@ attr.c: static void bootstrap_attr_stack(struct index_state *istate,
      	if (*stack)
      		return;
     @@ attr.c: static void bootstrap_attr_stack(struct index_state *istate,
    - 		push_stack(stack, e, NULL, 0);
      	}
      
    --	/* home directory */
    + 	/* home directory */
     -	if (git_attr_global_file()) {
     -		e = read_attr_from_file(git_attr_global_file(), flags);
     +	if (istate && istate->repo)
    @@ repo-settings.c: 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);
    ++	FREE_AND_NULL(r->settings.attributes_file_path);
      	r->settings = empty;
      }
      
    @@ repo-settings.c: void repo_settings_reset_shared_repository(struct repository *r
      }
     +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");
    ++	if (!repo->settings.attributes_file_path) {
    ++		if (repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.attributes_file_path))
    ++			repo->settings.attributes_file_path = xdg_config_home("attributes");
     +	}
    -+	return repo->settings.git_attributes_file;
    ++	return repo->settings.attributes_file_path;
     +}
     
      ## repo-settings.h ##
    @@ repo-settings.h: struct repo_settings {
      	unsigned long big_file_threshold;
      
      	char *hooks_path;
    -+	char *git_attributes_file;
    ++	char *attributes_file_path;
      };
      #define REPO_SETTINGS_INIT { \
      	.shared_repository = -1, \
    @@ repo-settings.h: int repo_settings_get_shared_repository(struct repository *repo
     +/*
     + * Read the value for "core.attributesfile".
     + * Defaults to xdg_config_home("attributes") if the core.attributesfile
    -+ * isn't available.
    ++ * which is set via repo config isn't available.
     + */
     +const char *repo_settings_get_attributesfile_path(struct repository *repo);
     +

 attr.c          | 19 +++++++++----------
 attr.h          |  3 ---
 builtin/var.c   |  2 +-
 environment.c   |  6 ------
 environment.h   |  1 -
 repo-settings.c | 10 ++++++++++
 repo-settings.h |  8 ++++++++
 7 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/attr.c b/attr.c
index 4999b7e09d..b081400c18 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);
@@ -912,6 +904,8 @@ static void bootstrap_attr_stack(struct index_state *istate,
 {
 	struct attr_stack *e;
 	unsigned flags = READ_ATTR_MACRO_OK;
+	const char *attributes_file_path;
+	struct repository *repo;
 
 	if (*stack)
 		return;
@@ -927,8 +921,13 @@ 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);
+	if (istate && istate->repo)
+		repo = istate->repo;
+	else
+		repo = the_repository;
+	attributes_file_path = repo_settings_get_attributesfile_path(repo);
+	if (attributes_file_path) {
+		e = read_attr_from_file(attributes_file_path, flags);
 		push_stack(stack, e, NULL, 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/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/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..cc53a3cd3b 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.attributes_file_path);
 	r->settings = empty;
 }
 
@@ -230,3 +232,11 @@ 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.attributes_file_path) {
+		if (repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.attributes_file_path))
+			repo->settings.attributes_file_path = xdg_config_home("attributes");
+	}
+	return repo->settings.attributes_file_path;
+}
diff --git a/repo-settings.h b/repo-settings.h
index d477885561..1209e1db83 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 *attributes_file_path;
 };
 #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.attributesfile
+ * which is set via repo config isn't available.
+ */
+const char *repo_settings_get_attributesfile_path(struct repository *repo);
+
 #endif /* REPO_SETTINGS_H */
-- 
2.52.0.210.g7f9f2609ac.dirty


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-02 16:32 ` [Outreachy PATCH v2] " Olamide Caleb Bello
@ 2026-01-05 11:09   ` Karthik Nayak
  2026-01-05 11:39     ` Bello Olamide
  2026-01-05 14:23   ` Phillip Wood
  1 sibling, 1 reply; 21+ messages in thread
From: Karthik Nayak @ 2026-01-05 11:09 UTC (permalink / raw)
  To: Olamide Caleb Bello, git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

[-- Attachment #1: Type: text/plain, Size: 633 bytes --]

Olamide Caleb Bello <belkid98@gmail.com> writes:
[snip]

> @@ -927,8 +921,13 @@ 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);
> +	if (istate && istate->repo)
> +		repo = istate->repo;
> +	else
> +		repo = the_repository;
> +	attributes_file_path = repo_settings_get_attributesfile_path(repo);
> +	if (attributes_file_path) {
> +		e = read_attr_from_file(attributes_file_path, flags);
>  		push_stack(stack, e, NULL, 0);
>  	}
>

For my own understanding, when can `istate` be NULL?

[snip]

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 690 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 11:09   ` Karthik Nayak
@ 2026-01-05 11:39     ` Bello Olamide
  0 siblings, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2026-01-05 11:39 UTC (permalink / raw)
  To: Karthik Nayak
  Cc: git, gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau

On Mon, 5 Jan 2026 at 12:09, Karthik Nayak <karthik.188@gmail.com> wrote:
>
> Olamide Caleb Bello <belkid98@gmail.com> writes:
> [snip]
>
> > @@ -927,8 +921,13 @@ 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);
> > +     if (istate && istate->repo)
> > +             repo = istate->repo;
> > +     else
> > +             repo = the_repository;
> > +     attributes_file_path = repo_settings_get_attributesfile_path(repo);
> > +     if (attributes_file_path) {
> > +             e = read_attr_from_file(attributes_file_path, flags);
> >               push_stack(stack, e, NULL, 0);
> >       }
> >
>
> For my own understanding, when can `istate` be NULL?
>

Thank you for your question Karthik.
So it was stated in a comment in `apply.c:read_old_data():2340` that
`git apply without --index/cached
should never look at the index because the target file may not be in
the index yet
and we may not be in a Git repository.`
So NULL is passed to convert_to_git() in place of `istate`.

So when we do
`git apply patch.file` `istate` is NULL, but when we do
`git apply --cached patch.file`, `istate` is not NULL.

Bello

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-02 16:32 ` [Outreachy PATCH v2] " Olamide Caleb Bello
  2026-01-05 11:09   ` Karthik Nayak
@ 2026-01-05 14:23   ` Phillip Wood
  2026-01-05 15:00     ` Phillip Wood
                       ` (2 more replies)
  1 sibling, 3 replies; 21+ messages in thread
From: Phillip Wood @ 2026-01-05 14:23 UTC (permalink / raw)
  To: Olamide Caleb Bello, git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

Hi Olamide

On 02/01/2026 16:32, Olamide Caleb Bello wrote:
> 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.
> The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> retrieve "core.attributesFile" via `git_attr_global_file()`
> which reads from global state `git_attributes_file`.
> 
> Move the "core.attributesFile" configuration into the
> `struct repo_settings` instead of relying on the global state.

This changes when the config setting gets parsed which unfortunately 
regresses the user experience when the setting is invalid.

If I run 'git -c core.attributesFile=~does-not-exist rebase -i' with git 
built from master it fails immediately with "fatal: failed to expand 
user dir in: '~does-not-exist'". With this patch applied it prompts me 
to edit the todo list and then fails when it tries to checkout the 
commit we're rebasing onto. Because "git rebase" expects reset_head() to 
return an error rather die if the checkout fails it is left in a strange 
state where only practical course of action for the user is to run "git 
rebase --abort".

It is quite common that moving from parsing config settings eagerly by 
calling repo_config() at startup to parsing them lazily via 'stuct 
repo_settings' causes regressions like this. We really should find a way 
to address that before moving more settings into 'struct repo_settings'

Thanks

Phillip


> A new function `repo_settings_get_attributesfile_path()` is added
> and used to retrieve this setting in a repository-scoped manner.
> The functions to retrieve "core.attributesFile" are replaced with
> the new accessor function `repo_settings_get_attributesfile_path()`
> This improves multi-repository behaviour and aligns with the goal of
> libifying of Git.
> 
> Note that in `bootstrap_attr_stack()`, the `index_state` is used only
> if it exists, else we default to `the_repository`.
> 
> Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
> ---
> The link to the GitHub CI is provided below
> https://github.com/git/git/actions/runs/20661817110
> 
> Changes in v2:
> --------------
> - Renamed the variable in the repo-settings struct to `attributes_file_path`
> - Modified the comment section of the accessor function declaration to
>    indicate the core.attributesFile is read via repo config.
> 
> Range diff vs v1:
> -----------------
> 1:  4975f77cde ! 1:  fc1dbec892 environment: move "core.attributesfile" into repo-setting
>      @@ Commit message
>           Note that in `bootstrap_attr_stack()`, the `index_state` is used only
>           if it exists, else we default to `the_repository`.
>       
>      -    Reported-by: Ayush Chandekar <ayu.chandekar@gmail.com>
>      +    Based-on-patch-by: Ayush Chandekar <ayu.chandekar@gmail.com>
>           Mentored-by: Christian Couder <christian.couder@gmail.com>
>           Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
>           Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
>      @@ attr.c: static void bootstrap_attr_stack(struct index_state *istate,
>        	if (*stack)
>        		return;
>       @@ attr.c: static void bootstrap_attr_stack(struct index_state *istate,
>      - 		push_stack(stack, e, NULL, 0);
>        	}
>        
>      --	/* home directory */
>      + 	/* home directory */
>       -	if (git_attr_global_file()) {
>       -		e = read_attr_from_file(git_attr_global_file(), flags);
>       +	if (istate && istate->repo)
>      @@ repo-settings.c: 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);
>      ++	FREE_AND_NULL(r->settings.attributes_file_path);
>        	r->settings = empty;
>        }
>        
>      @@ repo-settings.c: void repo_settings_reset_shared_repository(struct repository *r
>        }
>       +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");
>      ++	if (!repo->settings.attributes_file_path) {
>      ++		if (repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.attributes_file_path))
>      ++			repo->settings.attributes_file_path = xdg_config_home("attributes");
>       +	}
>      -+	return repo->settings.git_attributes_file;
>      ++	return repo->settings.attributes_file_path;
>       +}
>       
>        ## repo-settings.h ##
>      @@ repo-settings.h: struct repo_settings {
>        	unsigned long big_file_threshold;
>        
>        	char *hooks_path;
>      -+	char *git_attributes_file;
>      ++	char *attributes_file_path;
>        };
>        #define REPO_SETTINGS_INIT { \
>        	.shared_repository = -1, \
>      @@ repo-settings.h: int repo_settings_get_shared_repository(struct repository *repo
>       +/*
>       + * Read the value for "core.attributesfile".
>       + * Defaults to xdg_config_home("attributes") if the core.attributesfile
>      -+ * isn't available.
>      ++ * which is set via repo config isn't available.
>       + */
>       +const char *repo_settings_get_attributesfile_path(struct repository *repo);
>       +
> 
>   attr.c          | 19 +++++++++----------
>   attr.h          |  3 ---
>   builtin/var.c   |  2 +-
>   environment.c   |  6 ------
>   environment.h   |  1 -
>   repo-settings.c | 10 ++++++++++
>   repo-settings.h |  8 ++++++++
>   7 files changed, 28 insertions(+), 21 deletions(-)
> 
> diff --git a/attr.c b/attr.c
> index 4999b7e09d..b081400c18 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);
> @@ -912,6 +904,8 @@ static void bootstrap_attr_stack(struct index_state *istate,
>   {
>   	struct attr_stack *e;
>   	unsigned flags = READ_ATTR_MACRO_OK;
> +	const char *attributes_file_path;
> +	struct repository *repo;
>   
>   	if (*stack)
>   		return;
> @@ -927,8 +921,13 @@ 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);
> +	if (istate && istate->repo)
> +		repo = istate->repo;
> +	else
> +		repo = the_repository;
> +	attributes_file_path = repo_settings_get_attributesfile_path(repo);
> +	if (attributes_file_path) {
> +		e = read_attr_from_file(attributes_file_path, flags);
>   		push_stack(stack, e, NULL, 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/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/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..cc53a3cd3b 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.attributes_file_path);
>   	r->settings = empty;
>   }
>   
> @@ -230,3 +232,11 @@ 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.attributes_file_path) {
> +		if (repo_config_get_pathname(repo, "core.attributesfile", &repo->settings.attributes_file_path))
> +			repo->settings.attributes_file_path = xdg_config_home("attributes");
> +	}
> +	return repo->settings.attributes_file_path;
> +}
> diff --git a/repo-settings.h b/repo-settings.h
> index d477885561..1209e1db83 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 *attributes_file_path;
>   };
>   #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.attributesfile
> + * which is set via repo config isn't available.
> + */
> +const char *repo_settings_get_attributesfile_path(struct repository *repo);
> +
>   #endif /* REPO_SETTINGS_H */


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 14:23   ` Phillip Wood
@ 2026-01-05 15:00     ` Phillip Wood
  2026-01-05 22:28       ` Junio C Hamano
  2026-01-06  8:09       ` Bello Olamide
  2026-01-05 22:24     ` Junio C Hamano
  2026-01-06  8:08     ` Bello Olamide
  2 siblings, 2 replies; 21+ messages in thread
From: Phillip Wood @ 2026-01-05 15:00 UTC (permalink / raw)
  To: Olamide Caleb Bello, git
  Cc: gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

On 05/01/2026 14:23, Phillip Wood wrote:
> 
> It is quite common that moving from parsing config settings eagerly by 
> calling repo_config() at startup to parsing them lazily via 'stuct 
> repo_settings' causes regressions like this. We really should find a way 
> to address that before moving more settings into 'struct repo_settings'

See 
https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com 
for some discussion about a possible solution.

Thanks

Phillip


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 14:23   ` Phillip Wood
  2026-01-05 15:00     ` Phillip Wood
@ 2026-01-05 22:24     ` Junio C Hamano
  2026-01-07 10:17       ` Phillip Wood
  2026-01-06  8:08     ` Bello Olamide
  2 siblings, 1 reply; 21+ messages in thread
From: Junio C Hamano @ 2026-01-05 22:24 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Olamide Caleb Bello, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

Phillip Wood <phillip.wood123@gmail.com> writes:

> If I run 'git -c core.attributesFile=~does-not-exist rebase -i' with git 
> built from master it fails immediately with "fatal: failed to expand 
> user dir in: '~does-not-exist'".

Hmph, if you call any behaviour change a "regression", this may
certainly count as one, but I do not necessarily think the above is
a good behaviour.

Think about a use case where attributes are not used at all, e.g.,
"git -c core.attributesFile=~does-not-matter cat-file -t HEAD";
would it make sense to barf when your configuration file has an
invalid definition for what you are *not* using?  So if the change
makes it stop barfing, it can even be argued that this is an
improvement.

> It is quite common that moving from parsing config settings eagerly by 
> calling repo_config() at startup to parsing them lazily via 'stuct 
> repo_settings' causes regressions like this. We really should find a way 
> to address that before moving more settings into 'struct repo_settings'

Very true.  If we know the set of things we parse early and have a
way to say "this command only X, Y, and Z matters (but not W)", then
the above cat-file example can omit the attributesFile from the "we
care" set.

I think overusing repo_settings is a disease.  Moving a singleton
global to per repository (by adding to struct repository) is one
thing and it is very welcome.  But changing the way configuration
variables are parsed (e.g., what used to be parsed by only those who
care about is now parsed by everybody, or vice versa) needs to be
handled carefully.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 15:00     ` Phillip Wood
@ 2026-01-05 22:28       ` Junio C Hamano
  2026-01-06  9:33         ` Bello Olamide
  2026-01-06  8:09       ` Bello Olamide
  1 sibling, 1 reply; 21+ messages in thread
From: Junio C Hamano @ 2026-01-05 22:28 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Olamide Caleb Bello, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

Phillip Wood <phillip.wood123@gmail.com> writes:

> On 05/01/2026 14:23, Phillip Wood wrote:
>> 
>> It is quite common that moving from parsing config settings eagerly by 
>> calling repo_config() at startup to parsing them lazily via 'stuct 
>> repo_settings' causes regressions like this. We really should find a way 
>> to address that before moving more settings into 'struct repo_settings'
>
> See 
> https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com 
> for some discussion about a possible solution.

Nice, but I suspect it would be an improvement already without
passing repository instance via git_default_config() and instead
have the code use the_repository; it is even possible not to have
any repository when the callchain executes.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 14:23   ` Phillip Wood
  2026-01-05 15:00     ` Phillip Wood
  2026-01-05 22:24     ` Junio C Hamano
@ 2026-01-06  8:08     ` Bello Olamide
  2 siblings, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2026-01-06  8:08 UTC (permalink / raw)
  To: phillip.wood
  Cc: git, gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

On Mon, 5 Jan 2026 at 15:23, Phillip Wood <phillip.wood123@gmail.com> wrote:
>
> Hi Olamide
>
> On 02/01/2026 16:32, Olamide Caleb Bello wrote:
> > 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.
> > The functions `bootstrap_attr_stack()` and `git_attr_val_system()`
> > retrieve "core.attributesFile" via `git_attr_global_file()`
> > which reads from global state `git_attributes_file`.
> >
> > Move the "core.attributesFile" configuration into the
> > `struct repo_settings` instead of relying on the global state.
>
> This changes when the config setting gets parsed which unfortunately
> regresses the user experience when the setting is invalid.
>
> If I run 'git -c core.attributesFile=~does-not-exist rebase -i' with git
> built from master it fails immediately with "fatal: failed to expand
> user dir in: '~does-not-exist'". With this patch applied it prompts me
> to edit the todo list and then fails when it tries to checkout the
> commit we're rebasing onto. Because "git rebase" expects reset_head() to
> return an error rather die if the checkout fails it is left in a strange
> state where only practical course of action for the user is to run "git
> rebase --abort".

Yes I tried this and I experienced the same behaviour.

>
> It is quite common that moving from parsing config settings eagerly by
> calling repo_config() at startup to parsing them lazily via 'stuct
> repo_settings' causes regressions like this. We really should find a way
> to address that before moving more settings into 'struct repo_settings'
>

Yes, I came across an initial discussion about `prepare_repo_settings()`
and the issues about the appropriate place to call it but it seemed there was
no resolution then.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 15:00     ` Phillip Wood
  2026-01-05 22:28       ` Junio C Hamano
@ 2026-01-06  8:09       ` Bello Olamide
  1 sibling, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2026-01-06  8:09 UTC (permalink / raw)
  To: phillip.wood
  Cc: git, gitster, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

On Mon, 5 Jan 2026 at 16:00, Phillip Wood <phillip.wood123@gmail.com> wrote:
>
> On 05/01/2026 14:23, Phillip Wood wrote:
> >
> > It is quite common that moving from parsing config settings eagerly by
> > calling repo_config() at startup to parsing them lazily via 'stuct
> > repo_settings' causes regressions like this. We really should find a way
> > to address that before moving more settings into 'struct repo_settings'
>
> See
> https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com
> for some discussion about a possible solution.

Yes, thank you.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 22:28       ` Junio C Hamano
@ 2026-01-06  9:33         ` Bello Olamide
  2026-01-06 13:44           ` Bello Olamide
  0 siblings, 1 reply; 21+ messages in thread
From: Bello Olamide @ 2026-01-06  9:33 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Phillip Wood, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

On Mon, 5 Jan 2026 at 23:28, Junio C Hamano <gitster@pobox.com> wrote:
>
> Phillip Wood <phillip.wood123@gmail.com> writes:
>
> > On 05/01/2026 14:23, Phillip Wood wrote:
> >>
> >> It is quite common that moving from parsing config settings eagerly by
> >> calling repo_config() at startup to parsing them lazily via 'stuct
> >> repo_settings' causes regressions like this. We really should find a way
> >> to address that before moving more settings into 'struct repo_settings'
> >
> > See
> > https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com
> > for some discussion about a possible solution.
>
> Nice, but I suspect it would be an improvement already without
> passing repository instance via git_default_config() and instead
> have the code use the_repository; it is even possible not to have
> any repository when the callchain executes.

Thank you Junio.
Okay, should I move the variable into the repo struct or repo-settings struct
as the case may be, then initialize it in git_default_config()?

For example
`
         if (!strcmp(var, "core.attributesfile")) {
              FREE_AND_NULL(the_repository->settings.git_attributes_file);
              return
git_config_pathname(&the_repository->settings.git_attributes_file,
var, value);
            }
`
Does this sound reasonable?

Also the `git_default_core_config()` is used to initialize the
variables to store the settings
in the "core" section of the config file.
So how about other functions like `git _default_branch_config()`,
`git _default-sparse_config()`.
Do I use the same approach above?

Thanks

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-06  9:33         ` Bello Olamide
@ 2026-01-06 13:44           ` Bello Olamide
  2026-01-07 10:26             ` Phillip Wood
  0 siblings, 1 reply; 21+ messages in thread
From: Bello Olamide @ 2026-01-06 13:44 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Phillip Wood, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

On Tue, 6 Jan 2026 at 10:33, Bello Olamide <belkid98@gmail.com> wrote:
>
> On Mon, 5 Jan 2026 at 23:28, Junio C Hamano <gitster@pobox.com> wrote:
> >
> > Phillip Wood <phillip.wood123@gmail.com> writes:
> >
> > > On 05/01/2026 14:23, Phillip Wood wrote:
> > >>
> > >> It is quite common that moving from parsing config settings eagerly by
> > >> calling repo_config() at startup to parsing them lazily via 'stuct
> > >> repo_settings' causes regressions like this. We really should find a way
> > >> to address that before moving more settings into 'struct repo_settings'
> > >
> > > See
> > > https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com
> > > for some discussion about a possible solution.
> >
> > Nice, but I suspect it would be an improvement already without
> > passing repository instance via git_default_config() and instead
> > have the code use the_repository; it is even possible not to have
> > any repository when the callchain executes.

But won't this be a temporary solution since the goal is to prevent the use of
`the_repository`?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-05 22:24     ` Junio C Hamano
@ 2026-01-07 10:17       ` Phillip Wood
  0 siblings, 0 replies; 21+ messages in thread
From: Phillip Wood @ 2026-01-07 10:17 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Olamide Caleb Bello, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

On 05/01/2026 22:24, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>> If I run 'git -c core.attributesFile=~does-not-exist rebase -i' with git
>> built from master it fails immediately with "fatal: failed to expand
>> user dir in: '~does-not-exist'".
> 
> Hmph, if you call any behaviour change a "regression", this may
> certainly count as one, but I do not necessarily think the above is
> a good behaviour.

One can argue that it depends on the command, but a as far as "git 
rebase" is concerned this change in behavior is a regression. It is not 
just rebase that is affected, for example "git merge" in a partial clone 
now downloads all the blobs it wants before erroring out which isn't 
terrible but it is hard to argue that's an improvement. I suspect "git 
cherry-pick" and "git revert" are also negatively impacted by this change.

> Think about a use case where attributes are not used at all, e.g.,
> "git -c core.attributesFile=~does-not-matter cat-file -t HEAD";
> would it make sense to barf when your configuration file has an
> invalid definition for what you are *not* using?  So if the change
> makes it stop barfing, it can even be argued that this is an
> improvement.

For some commands, but the fact that other commands now die when they're 
not expecting to and so end up in a strange state is a regression. Given 
how widespread the use of attributes is it would be hard to audit all 
the affected code paths and adjust them to the new behavior.

>> It is quite common that moving from parsing config settings eagerly by
>> calling repo_config() at startup to parsing them lazily via 'stuct
>> repo_settings' causes regressions like this. We really should find a way
>> to address that before moving more settings into 'struct repo_settings'
> 
> Very true.  If we know the set of things we parse early and have a
> way to say "this command only X, Y, and Z matters (but not W)", then
> the above cat-file example can omit the attributesFile from the "we
> care" set.

That would be nice, but it would be painful to implement for commands 
like cat-file which sometimes need to read core.attributesFile and 
sometimes don't depending on which options they're passed as we 
typically read the config before parsing the command line options. We'd 
also need to be careful to update the list when adding new features 
which depended on config variables that were not previously used by that 
command.

> I think overusing repo_settings is a disease.  Moving a singleton
> global to per repository (by adding to struct repository) is one
> thing and it is very welcome.  But changing the way configuration
> variables are parsed (e.g., what used to be parsed by only those who
> care about is now parsed by everybody, or vice versa) needs to be
> handled carefully.

Indeed

Thanks

Phillip


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-06 13:44           ` Bello Olamide
@ 2026-01-07 10:26             ` Phillip Wood
  2026-01-07 14:18               ` Phillip Wood
  0 siblings, 1 reply; 21+ messages in thread
From: Phillip Wood @ 2026-01-07 10:26 UTC (permalink / raw)
  To: Bello Olamide, Junio C Hamano
  Cc: git, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

On 06/01/2026 13:44, Bello Olamide wrote:
> On Tue, 6 Jan 2026 at 10:33, Bello Olamide <belkid98@gmail.com> wrote:
>>
>> On Mon, 5 Jan 2026 at 23:28, Junio C Hamano <gitster@pobox.com> wrote:
>>>
>>> Phillip Wood <phillip.wood123@gmail.com> writes:
>>>
>>>> On 05/01/2026 14:23, Phillip Wood wrote:
>>>>>
>>>>> It is quite common that moving from parsing config settings eagerly by
>>>>> calling repo_config() at startup to parsing them lazily via 'stuct
>>>>> repo_settings' causes regressions like this. We really should find a way
>>>>> to address that before moving more settings into 'struct repo_settings'
>>>>
>>>> See
>>>> https://lore.kernel.org/git/d61c966b-61ae-4ba9-b983-c8dab6e2c292@gmail.com
>>>> for some discussion about a possible solution.
>>>
>>> Nice, but I suspect it would be an improvement already without
>>> passing repository instance via git_default_config() and instead
>>> have the code use the_repository; it is even possible not to have
>>> any repository when the callchain executes.
> 
> But won't this be a temporary solution since the goal is to prevent the use of
> `the_repository`?

Yes but it would be a good start as passing a repository down to 
git_default_config() will be quite invasive. It would certainly be 
better if we can find a solution that uses the repository passed to 
command when it is non-NULL. Unfortunately commands like "git diff 
--no-index" are passed a NULL repository but we have chosen to store our 
config in a `struct repository` and so we need some kind of fake 
repository for those commands. If we stored our config in a separate 
struct we wouldn't need to fake a repository but then we'd have to pass 
the config round separately to the repository which is a pain. Perhaps 
git_default_config() could use `the_repository` when it's given a NULL 
pointer for the callback data.

Thanks

Phillip


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-07 10:26             ` Phillip Wood
@ 2026-01-07 14:18               ` Phillip Wood
  2026-01-07 15:33                 ` Bello Olamide
  0 siblings, 1 reply; 21+ messages in thread
From: Phillip Wood @ 2026-01-07 14:18 UTC (permalink / raw)
  To: Bello Olamide, Junio C Hamano
  Cc: git, Christian Couder, Usman Akinyemi, Kaartic Sivaraam,
	Taylor Blau, Karthik Nayak

On 07/01/2026 10:26, Phillip Wood wrote:
> On 06/01/2026 13:44, Bello Olamide wrote:
>>
>> But won't this be a temporary solution since the goal is to prevent 
>> the use of
>> `the_repository`?
> 
> Yes but it would be a good start as passing a repository down to 
> git_default_config() will be quite invasive.

To expand on this the first steps could be
   (i) create a new struct to hold the config settings from
       git_default_config()
  (ii) add that struct as a member of `struct repository`
(iii) one-by-one, for each setting parsed by git_default_config() add a
       new member to the config struct, store the parsed value in
       `the_repository` and adjust any code that uses the variable.

Then later we can tackle the intrusive change to pass a `struct 
repository` down to git_default_config() and store the settings in that 
rather than `the_repository`. If we add a local variable to 
git_default_config() in step (iii) above then getting it to use the 
repository passed down the call chain will simply be a matter of doing 
something like

-	struct repository *r = the_repository;
+	struct repository *r = cb ? cb : the_repository;

Thanks

Phillip


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Outreachy PATCH v2] environment: move "core.attributesFile" into repo-setting
  2026-01-07 14:18               ` Phillip Wood
@ 2026-01-07 15:33                 ` Bello Olamide
  0 siblings, 0 replies; 21+ messages in thread
From: Bello Olamide @ 2026-01-07 15:33 UTC (permalink / raw)
  To: phillip.wood
  Cc: Junio C Hamano, git, Christian Couder, Usman Akinyemi,
	Kaartic Sivaraam, Taylor Blau, Karthik Nayak

On Wed, 7 Jan 2026 at 15:19, Phillip Wood <phillip.wood123@gmail.com> wrote:
>
> On 07/01/2026 10:26, Phillip Wood wrote:
> > On 06/01/2026 13:44, Bello Olamide wrote:
> >>
> >> But won't this be a temporary solution since the goal is to prevent
> >> the use of
> >> `the_repository`?
> >
> > Yes but it would be a good start as passing a repository down to
> > git_default_config() will be quite invasive.
>
> To expand on this the first steps could be
>    (i) create a new struct to hold the config settings from
>        git_default_config()
>   (ii) add that struct as a member of `struct repository`
> (iii) one-by-one, for each setting parsed by git_default_config() add a
>        new member to the config struct, store the parsed value in
>        `the_repository` and adjust any code that uses the variable.
>
> Then later we can tackle the intrusive change to pass a `struct
> repository` down to git_default_config() and store the settings in that
> rather than `the_repository`. If we add a local variable to
> git_default_config() in step (iii) above then getting it to use the
> repository passed down the call chain will simply be a matter of doing
> something like
>
> -       struct repository *r = the_repository;
> +       struct repository *r = cb ? cb : the_repository;
>
> Thanks
>
> Phillip
>

Thanks for the detailed proposal, which makes a lot of sense.
I’ll align my changes with this staged approach.

Bello

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-01-07 15:33 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-18  8:30 [Outreachy PATCH] environment: move "core.attributesFile" into repo-setting Olamide Caleb Bello
2025-12-18 17:31 ` Bello Olamide
2026-01-02  8:01 ` Bello Olamide
2026-01-02  8:49   ` Karthik Nayak
2026-01-02  8:48 ` Karthik Nayak
2026-01-02 11:26   ` Bello Olamide
2026-01-02 16:32 ` [Outreachy PATCH v2] " Olamide Caleb Bello
2026-01-05 11:09   ` Karthik Nayak
2026-01-05 11:39     ` Bello Olamide
2026-01-05 14:23   ` Phillip Wood
2026-01-05 15:00     ` Phillip Wood
2026-01-05 22:28       ` Junio C Hamano
2026-01-06  9:33         ` Bello Olamide
2026-01-06 13:44           ` Bello Olamide
2026-01-07 10:26             ` Phillip Wood
2026-01-07 14:18               ` Phillip Wood
2026-01-07 15:33                 ` Bello Olamide
2026-01-06  8:09       ` Bello Olamide
2026-01-05 22:24     ` Junio C Hamano
2026-01-07 10:17       ` Phillip Wood
2026-01-06  8:08     ` Bello Olamide

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).