summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2017-04-17 10:10:02 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-04-20 01:50:30 (GMT)
commite145a0bc9b8711fe1c6cfad29af52ef06ce4c1ec (patch)
tree9ad64ddf3cb267686cfa6d9f6bd19de04152a341 /config.c
parent2185fde56328942d5be9603cc199ee7c6d004085 (diff)
downloadgit-e145a0bc9b8711fe1c6cfad29af52ef06ce4c1ec.zip
git-e145a0bc9b8711fe1c6cfad29af52ef06ce4c1ec.tar.gz
git-e145a0bc9b8711fe1c6cfad29af52ef06ce4c1ec.tar.bz2
config: correct file reading order in read_early_config()
Config file reading order is important because each file can override values in the previous files and this is expected behavior. Normally we read in this order, all in do_git_config_sequence(): 1. $HOME/.gitconfig 2. $GIT_DIR/config 3. config from command line However in read_early_config() the order may be swapped a bit if setup_git_directory() has not been called: 1. $HOME/.gitconfig 2. $GIT_DIR/config is NOT read because .git dir is not found _yet_ 3. config from command line 4. $GIT_DIR/config is now READ (after discover_git_directory() call) The reading at step 4 could override config at step 3, which is not the expectation. Now that we could pass the .git dir around, we could feed discover_git_directory() back to step 2, so that it works again, and remove step 4. Noticed-by: Jeff King <peff@peff.net> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'config.c')
-rw-r--r--config.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/config.c b/config.c
index 14f0417..fffda65 100644
--- a/config.c
+++ b/config.c
@@ -1504,12 +1504,20 @@ int git_config_system(void)
return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
}
-static int do_git_config_sequence(config_fn_t fn, void *data)
+static int do_git_config_sequence(const struct config_options *opts,
+ config_fn_t fn, void *data)
{
int ret = 0;
char *xdg_config = xdg_config_home("config");
char *user_config = expand_user_path("~/.gitconfig");
- char *repo_config = have_git_dir() ? git_pathdup("config") : NULL;
+ char *repo_config;
+
+ if (opts->git_dir)
+ repo_config = mkpathdup("%s/config", opts->git_dir);
+ else if (have_git_dir())
+ repo_config = git_pathdup("config");
+ else
+ repo_config = NULL;
current_parsing_scope = CONFIG_SCOPE_SYSTEM;
if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0))
@@ -1563,7 +1571,7 @@ int git_config_with_options(config_fn_t fn, void *data,
else if (config_source && config_source->blob)
return git_config_from_blob_ref(fn, config_source->blob, data);
- return do_git_config_sequence(fn, data);
+ return do_git_config_sequence(opts, fn, data);
}
static void git_config_raw(config_fn_t fn, void *data)
@@ -1613,7 +1621,6 @@ void read_early_config(config_fn_t cb, void *data)
{
struct config_options opts = {0};
struct strbuf buf = STRBUF_INIT;
- char *to_free = NULL;
opts.respect_includes = 1;
@@ -1628,20 +1635,11 @@ void read_early_config(config_fn_t cb, void *data)
* call).
*/
else if (discover_git_directory(&buf))
- opts.git_dir = to_free = xstrdup(buf.buf);
+ opts.git_dir = buf.buf;
git_config_with_options(cb, data, NULL, &opts);
- if (!have_git_dir() && opts.git_dir) {
- struct git_config_source repo_config;
-
- memset(&repo_config, 0, sizeof(repo_config));
- strbuf_addstr(&buf, "/config");
- repo_config.file = buf.buf;
- git_config_with_options(cb, data, &repo_config, &opts);
- }
strbuf_release(&buf);
- free(to_free);
}
static void git_config_check_init(void);