Skip to content
20 changes: 12 additions & 8 deletions apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ struct gitdiff_data {
int p_value;
};

static void git_apply_config(void)
static void git_apply_config(struct repository *repo)
{
repo_config_get_string(the_repository, "apply.whitespace", &apply_default_whitespace);
repo_config_get_string(the_repository, "apply.ignorewhitespace", &apply_default_ignorewhitespace);
repo_config(the_repository, git_xmerge_config, NULL);
repo_config_get_string(repo, "apply.whitespace",
&repo_config_values(repo)->apply_default_whitespace);
repo_config_get_string(repo, "apply.ignorewhitespace",
&repo_config_values(repo)->apply_default_ignorewhitespace);
repo_config(repo, git_xmerge_config, NULL);
}

static int parse_whitespace_option(struct apply_state *state, const char *option)
Expand Down Expand Up @@ -126,10 +128,12 @@ int init_apply_state(struct apply_state *state,
strset_init(&state->kept_symlinks);
strbuf_init(&state->root, 0);

git_apply_config();
if (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))
git_apply_config(repo);
if (repo_config_values(repo)->apply_default_whitespace &&
parse_whitespace_option(state, repo_config_values(repo)->apply_default_whitespace))
return -1;
if (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))
if (repo_config_values(repo)->apply_default_ignorewhitespace &&
parse_ignorewhitespace_option(state, repo_config_values(repo)->apply_default_ignorewhitespace))
return -1;
return 0;
}
Expand Down Expand Up @@ -192,7 +196,7 @@ int check_apply_state(struct apply_state *state, int force_apply)

static void set_default_whitespace_mode(struct apply_state *state)
{
if (!state->whitespace_option && !apply_default_whitespace)
if (!state->whitespace_option && !repo_config_values(state->repo)->apply_default_whitespace)
state->ws_error_action = (state->apply ? warn_on_ws_error : nowarn_ws_error);
}

Expand Down
2 changes: 1 addition & 1 deletion branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static int find_tracked_branch(struct remote *remote, void *priv)

static int should_setup_rebase(const char *origin)
{
switch (autorebase) {
switch (repo_config_values(the_repository)->autorebase) {
case AUTOREBASE_NEVER:
return 0;
case AUTOREBASE_LOCAL:
Expand Down
8 changes: 4 additions & 4 deletions builtin/push.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref,
}
}

if (push_default == PUSH_DEFAULT_UPSTREAM &&
if (repo_config_values(the_repository)->push_default == PUSH_DEFAULT_UPSTREAM &&
skip_prefix(matched->name, "refs/heads/", &branch_name)) {
struct branch *branch = branch_get(branch_name);
if (branch->merge_nr == 1 && branch->merge[0]->src) {
Expand Down Expand Up @@ -160,7 +160,7 @@ static NORETURN void die_push_simple(struct branch *branch,
* Don't show advice for people who explicitly set
* push.default.
*/
if (push_default == PUSH_DEFAULT_UNSPECIFIED)
if (cfg->push_default == PUSH_DEFAULT_UNSPECIFIED)
advice_pushdefault_maybe = _("\n"
"To choose either option permanently, "
"see push.default in 'git help config'.\n");
Expand Down Expand Up @@ -232,7 +232,7 @@ static void setup_default_push_refspecs(int *flags, struct remote *remote)
const char *dst;
int same_remote;

switch (push_default) {
switch (repo_config_values(the_repository)->push_default) {
case PUSH_DEFAULT_MATCHING:
refspec_append(&rs, ":");
return;
Expand All @@ -252,7 +252,7 @@ static void setup_default_push_refspecs(int *flags, struct remote *remote)
dst = branch->refname;
same_remote = !strcmp(remote->name, remote_for_branch(branch, NULL));

switch (push_default) {
switch (repo_config_values(the_repository)->push_default) {
default:
case PUSH_DEFAULT_UNSPECIFIED:
case PUSH_DEFAULT_SIMPLE:
Expand Down
4 changes: 2 additions & 2 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3481,11 +3481,11 @@ static GIT_PATH_FUNC(git_path_info_exclude, "info/exclude")

void setup_standard_excludes(struct dir_struct *dir)
{
const char *excludes_file = repo_excludes_file(the_repository);

dir->exclude_per_dir = ".gitignore";

/* core.excludesfile defaulting to $XDG_CONFIG_HOME/git/ignore */
if (!excludes_file)
excludes_file = xdg_config_home("ignore");
if (excludes_file && !access_or_warn(excludes_file, R_OK, 0))
add_patterns_from_file_1(dir, excludes_file,
dir->untracked ? &dir->internal.ss_excludes_file : NULL);
Expand Down
4 changes: 2 additions & 2 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const char *git_editor(void)
const char *editor = getenv("GIT_EDITOR");
int terminal_is_dumb = is_terminal_dumb();

if (!editor && editor_program)
editor = editor_program;
if (!editor && repo_config_values(the_repository)->editor_program)
editor = repo_config_values(the_repository)->editor_program;
Comment thread
malon7782 marked this conversation as resolved.
if (!editor && !terminal_is_dumb)
editor = getenv("VISUAL");
if (!editor)
Expand Down
87 changes: 62 additions & 25 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,18 @@ int assume_unchanged;
int is_bare_repository_cfg = -1; /* unspecified */
char *git_commit_encoding;
char *git_log_output_encoding;
char *apply_default_whitespace;
char *apply_default_ignorewhitespace;
int fsync_object_files = -1;
int use_fsync = -1;
enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;
char *editor_program;
Comment thread
malon7782 marked this conversation as resolved.
char *askpass_program;
char *excludes_file;
enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
enum eol core_eol = EOL_UNSET;
int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
char *check_roundtrip_encoding;
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#ifndef OBJECT_CREATION_MODE
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
#endif
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
int grafts_keep_true_parents;
unsigned long pack_size_limit_cfg;

Expand Down Expand Up @@ -134,6 +127,14 @@ int is_bare_repository(void)
return is_bare_repository_cfg && !repo_get_work_tree(the_repository);
}

const char *repo_excludes_file(struct repository *repo)
{
if (!repo_config_values(repo)->excludes_file)
repo_config_values(repo)->excludes_file = xdg_config_home("ignore");

return repo_config_values(repo)->excludes_file;
}

int have_git_dir(void)
{
return startup_info->have_repository
Expand Down Expand Up @@ -428,8 +429,8 @@ int git_default_core_config(const char *var, const char *value,
}

if (!strcmp(var, "core.editor")) {
FREE_AND_NULL(editor_program);
return git_config_string(&editor_program, var, value);
FREE_AND_NULL(cfg->editor_program);
return git_config_string(&cfg->editor_program, var, value);
Comment thread
malon7782 marked this conversation as resolved.
Comment thread
malon7782 marked this conversation as resolved.
}

if (!strcmp(var, "core.commentchar") ||
Expand All @@ -456,13 +457,13 @@ int git_default_core_config(const char *var, const char *value,
}

if (!strcmp(var, "core.askpass")) {
FREE_AND_NULL(askpass_program);
return git_config_string(&askpass_program, var, value);
FREE_AND_NULL(cfg->askpass_program);
return git_config_string(&cfg->askpass_program, var, value);
}

if (!strcmp(var, "core.excludesfile")) {
FREE_AND_NULL(excludes_file);
return git_config_pathname(&excludes_file, var, value);
FREE_AND_NULL(cfg->excludes_file);
return git_config_pathname(&cfg->excludes_file, var, value);
}

if (!strcmp(var, "core.whitespace")) {
Expand Down Expand Up @@ -509,9 +510,9 @@ int git_default_core_config(const char *var, const char *value,
if (!value)
return config_error_nonbool(var);
if (!strcmp(value, "rename"))
object_creation_mode = OBJECT_CREATION_USES_RENAMES;
cfg->object_creation_mode = OBJECT_CREATION_USES_RENAMES;
else if (!strcmp(value, "link"))
object_creation_mode = OBJECT_CREATION_USES_HARDLINKS;
cfg->object_creation_mode = OBJECT_CREATION_USES_HARDLINKS;
else
die(_("invalid mode for object creation: %s"), value);
return 0;
Expand Down Expand Up @@ -597,13 +598,13 @@ static int git_default_branch_config(const char *var, const char *value)
if (!value)
return config_error_nonbool(var);
else if (!strcmp(value, "never"))
autorebase = AUTOREBASE_NEVER;
cfg->autorebase = AUTOREBASE_NEVER;
else if (!strcmp(value, "local"))
autorebase = AUTOREBASE_LOCAL;
cfg->autorebase = AUTOREBASE_LOCAL;
else if (!strcmp(value, "remote"))
autorebase = AUTOREBASE_REMOTE;
cfg->autorebase = AUTOREBASE_REMOTE;
else if (!strcmp(value, "always"))
autorebase = AUTOREBASE_ALWAYS;
cfg->autorebase = AUTOREBASE_ALWAYS;
else
return error(_("malformed value for %s"), var);
return 0;
Expand All @@ -615,21 +616,23 @@ static int git_default_branch_config(const char *var, const char *value)

static int git_default_push_config(const char *var, const char *value)
{
struct repo_config_values *cfg = repo_config_values(the_repository);

if (!strcmp(var, "push.default")) {
if (!value)
return config_error_nonbool(var);
else if (!strcmp(value, "nothing"))
push_default = PUSH_DEFAULT_NOTHING;
cfg->push_default = PUSH_DEFAULT_NOTHING;
else if (!strcmp(value, "matching"))
push_default = PUSH_DEFAULT_MATCHING;
cfg->push_default = PUSH_DEFAULT_MATCHING;
else if (!strcmp(value, "simple"))
push_default = PUSH_DEFAULT_SIMPLE;
cfg->push_default = PUSH_DEFAULT_SIMPLE;
else if (!strcmp(value, "upstream"))
push_default = PUSH_DEFAULT_UPSTREAM;
cfg->push_default = PUSH_DEFAULT_UPSTREAM;
else if (!strcmp(value, "tracking")) /* deprecated */
push_default = PUSH_DEFAULT_UPSTREAM;
cfg->push_default = PUSH_DEFAULT_UPSTREAM;
else if (!strcmp(value, "current"))
push_default = PUSH_DEFAULT_CURRENT;
cfg->push_default = PUSH_DEFAULT_CURRENT;
else {
error(_("malformed value for %s: %s"), var, value);
return error(_("must be one of nothing, matching, simple, "
Expand Down Expand Up @@ -715,6 +718,15 @@ int git_default_config(const char *var, const char *value,
void repo_config_values_init(struct repo_config_values *cfg)
{
cfg->attributes_file = NULL;
cfg->excludes_file = NULL;
cfg->editor_program = NULL;
cfg->pager_program = NULL;
cfg->askpass_program = NULL;
cfg->apply_default_whitespace = NULL;
cfg->apply_default_ignorewhitespace = NULL;
cfg->push_default = PUSH_DEFAULT_UNSPECIFIED;
cfg->autorebase = AUTOREBASE_NEVER;
cfg->object_creation_mode = OBJECT_CREATION_MODE;
cfg->apply_sparse_checkout = 0;
cfg->branch_track = BRANCH_TRACK_REMOTE;
cfg->trust_ctime = 1;
Expand All @@ -726,3 +738,28 @@ void repo_config_values_init(struct repo_config_values *cfg)
cfg->sparse_expect_files_outside_of_patterns = 0;
cfg->warn_on_object_refname_ambiguity = 1;
}

void repo_config_values_clear(struct repository *repo)
{
struct repo_config_values *cfg;

/*
* NEEDSWORK: Submodules are currently not supported by
* repo_config_values(), which explicitly BUG()s out if
* repo != the_repository. Since repo_clear() cleans up all
* repository instances, we must bypass them here to prevent
* crashing.
*/
if (repo != the_repository)
return;

cfg = repo_config_values(repo);

FREE_AND_NULL(cfg->attributes_file);
FREE_AND_NULL(cfg->excludes_file);
FREE_AND_NULL(cfg->editor_program);
FREE_AND_NULL(cfg->pager_program);
FREE_AND_NULL(cfg->askpass_program);
FREE_AND_NULL(cfg->apply_default_whitespace);
FREE_AND_NULL(cfg->apply_default_ignorewhitespace);
}
Loading
Loading