git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] environment: move access to "core.attributesfile" into repo settings

From
Patrick Steinhardt <ps@pks.im>
Date
Mar 10, 2025, 07:05 UTC
Message-ID
<Z86PUkJ1sbSH2VTU@pks.im>
In-Reply-To
<20250309153321.254844-1-ayu.chandekar@gmail.com>
On Sun, Mar 09, 2025 at 09:03:21PM +0530, Ayush Chandekar wrote:
Show 8 quoted lines
> Stop relying on global state to access the "core.attributesfile"
> configuration. Instead, store the value in `struct repo_settings` and
> retrieve it via `repo_settings_get_attributes_file_path()`.
> 
> This prevents incorrect values from being used when a user or tool is
> handling multiple repositories in the same process, each with different
> attribute configurations. It also improves repository isolation and helps
> progress towards libification by avoiding unnecessary global state.

We typically switch the order around a bit in our commit messages: we first explain what the actual problem is, and then we say how we fix it.

Show 19 quoted lines
> diff --git a/attr.c b/attr.c
> index 0bd2750528..aec4b42245 100644
> --- a/attr.c
> +++ b/attr.c
> @@ -879,12 +879,9 @@ const char *git_attr_system_file(void)
>  	return system_wide;
>  }
>  
> -const char *git_attr_global_file(void)
> +const char *git_attr_global_file(struct repository *repo)
>  {
> -	if (!git_attributes_file)
> -		git_attributes_file = xdg_config_home("attributes");
> -
> -	return git_attributes_file;
> +	return repo_settings_get_attributesfile_path(repo);
>  }
>  
>  int git_attr_system_is_enabled(void)

Hm. I wonder what the actual merit of this function is after the refactoring. Right now there isn't really any as it is a direct wrapper of `repo_settings_get_attributesfile_path()`.

Show 28 quoted lines
> diff --git a/attr.h b/attr.h
> index a04a521092..c4f26b8f58 100644
> --- a/attr.h
> +++ b/attr.h
> @@ -213,11 +213,13 @@ void git_check_attr(struct index_state *istate,
>  		    const char *path,
>  		    struct attr_check *check);
>  
> +struct repository;
> +
>  /*
>   * Retrieve all attributes that apply to the specified path.
>   * check holds the attributes and their values.
>   */
> -void git_all_attrs(struct index_state *istate,
> +void git_all_attrs(struct repository *repo, struct index_state *istate,
>  		   const char *path, struct attr_check *check);
>  
>  enum git_attr_direction {
> @@ -233,7 +235,7 @@ void attr_start(void);
>  const char *git_attr_system_file(void);
>  
>  /* Return the global gitattributes file, if any. */
> -const char *git_attr_global_file(void);
> +const char *git_attr_global_file(struct repository *repo);
>  
>  /* Return whether the system gitattributes file is enabled and should be used. */
>  int git_attr_system_is_enabled(void);

I think it would make sense to split out this change into a separate commit. The first commit would move the config into "repo-settings.c", the second commit would adapt functions and their callers as necessary.

Show 6 quoted lines
> @@ -283,4 +285,5 @@ struct match_attr {
>  struct match_attr *parse_attr_line(const char *line, const char *src,
>  				   int lineno, unsigned flags);
>  
> +
>  #endif /* ATTR_H */
Extraneous newline.
Show 41 quoted lines
> diff --git a/builtin/check-attr.c b/builtin/check-attr.c
> index 7cf275b893..1b8a89dfb2 100644
> --- a/builtin/check-attr.c
> +++ b/builtin/check-attr.c
> @@ -70,7 +70,7 @@ static void check_attr(const char *prefix, struct attr_check *check,
>  		prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
>  
>  	if (collect_all) {
> -		git_all_attrs(the_repository->index, full_path, check);
> +		git_all_attrs(the_repository, the_repository->index, full_path, check);
>  	} else {
>  		git_check_attr(the_repository->index, full_path, check);
>  	}
> diff --git a/builtin/var.c b/builtin/var.c
> index ada642a9fe..3d635c235e 100644
> --- a/builtin/var.c
> +++ b/builtin/var.c
> @@ -69,9 +69,9 @@ static char *git_attr_val_system(int ident_flag UNUSED)
>  	return NULL;
>  }
>  
> -static char *git_attr_val_global(int ident_flag UNUSED)
> +static char *repo_git_attr_val_global(struct repository *repo, int ident_flag UNUSED)
>  {
> -	char *file = xstrdup_or_null(git_attr_global_file());
> +	char *file = xstrdup_or_null(git_attr_global_file(repo));
>  	if (file) {
>  		normalize_path_copy(file, file);
>  		return file;
> @@ -79,6 +79,11 @@ static char *git_attr_val_global(int ident_flag UNUSED)
>  	return NULL;
>  }
>  
> +static char *git_attr_val_global(int ident_flag)
> +{
> +	return repo_git_attr_val_global(the_repository, ident_flag);
> +}
> +
>  static char *git_config_val_system(int ident_flag UNUSED)
>  {
>  	if (git_config_system()) {

I think we should just retain `git_attr_val_global()` and plug in `the_repository`. The extra change here doesn't add anything, and "builtin/var.c" being a builtin means is not reused anywhere else, either.

Show 16 quoted lines
> diff --git a/repo-settings.c b/repo-settings.c
> index 9d16d5399e..420ca72f5f 100644
> --- a/repo-settings.c
> +++ b/repo-settings.c
> @@ -167,3 +168,13 @@ 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_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");
> +		}
> +	}
We don't use curly braces around one-line statements.
> +	return repo->settings.git_attributes_file;
> +}

One thing I'm missing is the code to `free()` the allocated memory in `repo_settings_clear()`.

> \ No newline at end of file
Nit: missing newline at the end of the file.
Thanks!
Patrick
Previous: Ayush ChandekarNext: Ayush Chandekar
Message 2 of 18 in “environment: move access to "core.attributesfile" into repo settings”
  1. environment: move access to "core.attributesfile" into repo settingsAyush Chandekar, Mar 9, 2025
  2. Patrick SteinhardtMar 10, 2025
  3. Ayush ChandekarMar 10, 2025
  4. Junio C HamanoMar 10, 2025
  5. Ayush ChandekarMar 10, 2025
  6. Junio C HamanoMar 10, 2025
  7. 0/2 Stop depending on `the_repository` for core.attributesfileAyush Chandekar, Mar 10, 2025
  8. 1/2 environment: move access to "core.attributesfile" into repo settingsAyush Chandekar, Mar 10, 2025
  9. Karthik NayakMar 10, 2025
  10. 2/2 attr: use `repo_settings_get_attributesfile_path()` and update callersAyush Chandekar, Mar 10, 2025
  11. Karthik NayakMar 10, 2025
  12. Junio C HamanoMar 10, 2025
  13. Ayush ChandekarMar 11, 2025
  14. shejialuoMar 11, 2025
  15. Junio C HamanoMar 11, 2025
  16. Ayush ChandekarMar 11, 2025
  17. Outreachy intern: Request for the completion of this seriesOlamide Caleb Bello, Dec 8, 2025
  18. Bello OlamideDec 9, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.