mirror of
https://github.com/git/git.git
synced 2026-01-11 13:23:12 +09:00
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
249 lines
4.5 KiB
C
249 lines
4.5 KiB
C
/*
|
|
* GIT - The information manager from hell
|
|
*
|
|
* Copyright (C) Eric Biederman, 2005
|
|
*/
|
|
|
|
#define USE_THE_REPOSITORY_VARIABLE
|
|
|
|
#include "builtin.h"
|
|
|
|
#include "attr.h"
|
|
#include "config.h"
|
|
#include "editor.h"
|
|
#include "environment.h"
|
|
#include "ident.h"
|
|
#include "pager.h"
|
|
#include "refs.h"
|
|
#include "path.h"
|
|
#include "strbuf.h"
|
|
#include "run-command.h"
|
|
|
|
static const char var_usage[] = "git var (-l | <variable>)";
|
|
|
|
static char *committer(int ident_flag)
|
|
{
|
|
return xstrdup_or_null(git_committer_info(ident_flag));
|
|
}
|
|
|
|
static char *author(int ident_flag)
|
|
{
|
|
return xstrdup_or_null(git_author_info(ident_flag));
|
|
}
|
|
|
|
static char *editor(int ident_flag UNUSED)
|
|
{
|
|
return xstrdup_or_null(git_editor());
|
|
}
|
|
|
|
static char *sequence_editor(int ident_flag UNUSED)
|
|
{
|
|
return xstrdup_or_null(git_sequence_editor());
|
|
}
|
|
|
|
static char *pager(int ident_flag UNUSED)
|
|
{
|
|
const char *pgm = git_pager(the_repository, 1);
|
|
|
|
if (!pgm)
|
|
pgm = "cat";
|
|
return xstrdup(pgm);
|
|
}
|
|
|
|
static char *default_branch(int ident_flag UNUSED)
|
|
{
|
|
return repo_default_branch_name(the_repository, 1);
|
|
}
|
|
|
|
static char *shell_path(int ident_flag UNUSED)
|
|
{
|
|
return git_shell_path();
|
|
}
|
|
|
|
static char *git_attr_val_system(int ident_flag UNUSED)
|
|
{
|
|
if (git_attr_system_is_enabled()) {
|
|
char *file = xstrdup(git_attr_system_file());
|
|
normalize_path_copy(file, file);
|
|
return file;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static char *git_attr_val_global(int ident_flag UNUSED)
|
|
{
|
|
char *file = xstrdup_or_null(repo_settings_get_attributesfile_path(the_repository));
|
|
if (file) {
|
|
normalize_path_copy(file, file);
|
|
return file;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static char *git_config_val_system(int ident_flag UNUSED)
|
|
{
|
|
if (git_config_system()) {
|
|
char *file = git_system_config();
|
|
normalize_path_copy(file, file);
|
|
return file;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static char *git_config_val_global(int ident_flag UNUSED)
|
|
{
|
|
struct strbuf buf = STRBUF_INIT;
|
|
char *user, *xdg;
|
|
size_t unused;
|
|
|
|
git_global_config_paths(&user, &xdg);
|
|
if (xdg && *xdg) {
|
|
normalize_path_copy(xdg, xdg);
|
|
strbuf_addf(&buf, "%s\n", xdg);
|
|
}
|
|
if (user && *user) {
|
|
normalize_path_copy(user, user);
|
|
strbuf_addf(&buf, "%s\n", user);
|
|
}
|
|
free(xdg);
|
|
free(user);
|
|
strbuf_trim_trailing_newline(&buf);
|
|
if (buf.len == 0) {
|
|
strbuf_release(&buf);
|
|
return NULL;
|
|
}
|
|
return strbuf_detach(&buf, &unused);
|
|
}
|
|
|
|
struct git_var {
|
|
const char *name;
|
|
char *(*read)(int);
|
|
int multivalued;
|
|
};
|
|
static struct git_var git_vars[] = {
|
|
{
|
|
.name = "GIT_COMMITTER_IDENT",
|
|
.read = committer,
|
|
},
|
|
{
|
|
.name = "GIT_AUTHOR_IDENT",
|
|
.read = author,
|
|
},
|
|
{
|
|
.name = "GIT_EDITOR",
|
|
.read = editor,
|
|
},
|
|
{
|
|
.name = "GIT_SEQUENCE_EDITOR",
|
|
.read = sequence_editor,
|
|
},
|
|
{
|
|
.name = "GIT_PAGER",
|
|
.read = pager,
|
|
},
|
|
{
|
|
.name = "GIT_DEFAULT_BRANCH",
|
|
.read = default_branch,
|
|
},
|
|
{
|
|
.name = "GIT_SHELL_PATH",
|
|
.read = shell_path,
|
|
},
|
|
{
|
|
.name = "GIT_ATTR_SYSTEM",
|
|
.read = git_attr_val_system,
|
|
},
|
|
{
|
|
.name = "GIT_ATTR_GLOBAL",
|
|
.read = git_attr_val_global,
|
|
},
|
|
{
|
|
.name = "GIT_CONFIG_SYSTEM",
|
|
.read = git_config_val_system,
|
|
},
|
|
{
|
|
.name = "GIT_CONFIG_GLOBAL",
|
|
.read = git_config_val_global,
|
|
.multivalued = 1,
|
|
},
|
|
{
|
|
.name = "",
|
|
.read = NULL,
|
|
},
|
|
};
|
|
|
|
static void list_vars(void)
|
|
{
|
|
struct git_var *ptr;
|
|
char *val;
|
|
|
|
for (ptr = git_vars; ptr->read; ptr++)
|
|
if ((val = ptr->read(0))) {
|
|
if (ptr->multivalued && *val) {
|
|
struct string_list list = STRING_LIST_INIT_DUP;
|
|
|
|
string_list_split(&list, val, "\n", -1);
|
|
for (size_t i = 0; i < list.nr; i++)
|
|
printf("%s=%s\n", ptr->name, list.items[i].string);
|
|
string_list_clear(&list, 0);
|
|
} else {
|
|
printf("%s=%s\n", ptr->name, val);
|
|
}
|
|
free(val);
|
|
}
|
|
}
|
|
|
|
static const struct git_var *get_git_var(const char *var)
|
|
{
|
|
struct git_var *ptr;
|
|
for (ptr = git_vars; ptr->read; ptr++) {
|
|
if (strcmp(var, ptr->name) == 0) {
|
|
return ptr;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int show_config(const char *var, const char *value,
|
|
const struct config_context *ctx, void *cb)
|
|
{
|
|
if (value)
|
|
printf("%s=%s\n", var, value);
|
|
else
|
|
printf("%s\n", var);
|
|
return git_default_config(var, value, ctx, cb);
|
|
}
|
|
|
|
int cmd_var(int argc,
|
|
const char **argv,
|
|
const char *prefix UNUSED,
|
|
struct repository *repo UNUSED)
|
|
{
|
|
const struct git_var *git_var;
|
|
char *val;
|
|
|
|
show_usage_if_asked(argc, argv, var_usage);
|
|
if (argc != 2)
|
|
usage(var_usage);
|
|
|
|
if (strcmp(argv[1], "-l") == 0) {
|
|
repo_config(the_repository, show_config, NULL);
|
|
list_vars();
|
|
return 0;
|
|
}
|
|
repo_config(the_repository, git_default_config, NULL);
|
|
|
|
git_var = get_git_var(argv[1]);
|
|
if (!git_var)
|
|
usage(var_usage);
|
|
|
|
val = git_var->read(IDENT_STRICT);
|
|
if (!val)
|
|
return 1;
|
|
|
|
printf("%s\n", val);
|
|
free(val);
|
|
|
|
return 0;
|
|
}
|