diff options
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | config.c | 34 | ||||
-rwxr-xr-x | t/t1305-config-include.sh | 11 |
3 files changed, 38 insertions, 8 deletions
@@ -1887,6 +1887,7 @@ enum config_origin_type { struct config_options { unsigned int respect_includes : 1; + const char *git_dir; }; typedef int (*config_fn_t)(const char *, const char *, void *); @@ -207,13 +207,22 @@ static int prepare_include_condition_pattern(struct strbuf *pat) return prefix; } -static int include_by_gitdir(const char *cond, size_t cond_len, int icase) +static int include_by_gitdir(const struct config_options *opts, + const char *cond, size_t cond_len, int icase) { struct strbuf text = STRBUF_INIT; struct strbuf pattern = STRBUF_INIT; int ret = 0, prefix; + const char *git_dir; - strbuf_add_absolute_path(&text, get_git_dir()); + if (opts->git_dir) + git_dir = opts->git_dir; + else if (have_git_dir()) + git_dir = get_git_dir(); + else + goto done; + + strbuf_add_absolute_path(&text, git_dir); strbuf_add(&pattern, cond, cond_len); prefix = prepare_include_condition_pattern(&pattern); @@ -242,13 +251,14 @@ done: return ret; } -static int include_condition_is_true(const char *cond, size_t cond_len) +static int include_condition_is_true(const struct config_options *opts, + const char *cond, size_t cond_len) { if (skip_prefix_mem(cond, cond_len, "gitdir:", &cond, &cond_len)) - return include_by_gitdir(cond, cond_len, 0); + return include_by_gitdir(opts, cond, cond_len, 0); else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len)) - return include_by_gitdir(cond, cond_len, 1); + return include_by_gitdir(opts, cond, cond_len, 1); /* unknown conditionals are always false */ return 0; @@ -273,7 +283,7 @@ int git_config_include(const char *var, const char *value, void *data) ret = handle_path_include(value, inc); if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) && - (cond && include_condition_is_true(cond, cond_len)) && + (cond && include_condition_is_true(inc->opts, cond, cond_len)) && !strcmp(key, "path")) ret = handle_path_include(value, inc); @@ -1603,10 +1613,12 @@ 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; - git_config_with_options(cb, data, NULL, &opts); + if (have_git_dir()) + opts.git_dir = get_git_dir(); /* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there @@ -1615,7 +1627,12 @@ void read_early_config(config_fn_t cb, void *data) * notably, the current working directory is still the same after the * call). */ - if (!have_git_dir() && discover_git_directory(&buf)) { + else if (discover_git_directory(&buf)) + opts.git_dir = to_free = xstrdup(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)); @@ -1624,6 +1641,7 @@ void read_early_config(config_fn_t cb, void *data) git_config_with_options(cb, data, &repo_config, &opts); } strbuf_release(&buf); + free(to_free); } static void git_config_check_init(void); diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index e833939320..fddb47bafa 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -208,6 +208,17 @@ test_expect_success 'conditional include, both unanchored, icase' ' ) ' +test_expect_success 'conditional include, early config reading' ' + ( + cd foo && + echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config && + echo "[test]six=6" >.git/bar6 && + echo 6 >expect && + test-config read_early_config test.six >actual && + test_cmp expect actual + ) +' + test_expect_success 'include cycles are detected' ' cat >.gitconfig <<-\EOF && [test]value = gitconfig |