Skip to content

Commit 320c96b

Browse files
pks-tgitster
authored andcommitted
config: fix evaluating "onbranch" with nonexistent git dir
The `include_by_branch()` function is responsible for evaluating whether or not a specific include should be pulled in based on the currently checked out branch. Naturally, his condition can only be evaluated when we have a properly initialized repository with a ref store in the first place. This is why the function guards against the case when either `data->repo` or `data->repo->gitdir` are `NULL` pointers. But the second check is insufficient: the `gitdir` may be set even though the repository has not been initialized. Quoting "setup.c": NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some code paths so we also need to explicitly setup the environment if the user has set GIT_DIR. It may be beneficial to disallow bogus GIT_DIR values at some point in the future. So when either the GIT_DIR environment variable or the `--git-dir` global option are set by the user then `the_repository` may end up with an initialized `gitdir` variable. And this happens even when the dir is invalid, like for example when it doesn't exist. It follows that only checking for whether or not `gitdir` is `NULL` is not sufficient for us to determine whether the repository has been properly initialized. This issue can lead to us triggering a BUG: when using a config with an "includeIf.onbranch:" condition outside of a repository while using the `--git-dir` option pointing to an invalid Git directory we may end up trying to evaluate the condition even though the ref storage format has not been set up. This bisects to 173761e (setup: start tracking ref storage format, 2023-12-29), but that commit really only starts to surface the issue that has already existed beforehand. The code to check for `gitdir` was introduced via 85fe0e8 (config: work around bug with includeif:onbranch and early config, 2019-07-31), which tried to fix similar issues when we didn't yet have a repository set up. But the fix was incomplete as it missed the described scenario. As the quoted comment mentions, we'd ideally refactor the code to not set up `gitdir` with an invalid value in the first place, but that may be a bigger undertaking. Instead, refactor the code to use the ref storage format as an indicator of whether or not the ref store has been set up to fix the bug. Reported-by: Ronan Pigott <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9cc2590 commit 320c96b

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

config.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,16 @@ static int include_by_branch(struct config_include_data *data,
306306
int flags;
307307
int ret;
308308
struct strbuf pattern = STRBUF_INIT;
309-
const char *refname = (!data->repo || !data->repo->gitdir) ?
310-
NULL : refs_resolve_ref_unsafe(get_main_ref_store(data->repo),
311-
"HEAD", 0, NULL, &flags);
312-
const char *shortname;
309+
const char *refname, *shortname;
313310

314-
if (!refname || !(flags & REF_ISSYMREF) ||
315-
!skip_prefix(refname, "refs/heads/", &shortname))
311+
if (!data->repo || data->repo->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
312+
return 0;
313+
314+
refname = refs_resolve_ref_unsafe(get_main_ref_store(data->repo),
315+
"HEAD", 0, NULL, &flags);
316+
if (!refname ||
317+
!(flags & REF_ISSYMREF) ||
318+
!skip_prefix(refname, "refs/heads/", &shortname))
316319
return 0;
317320

318321
strbuf_add(&pattern, cond, cond_len);

t/t1305-config-include.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ test_expect_success 'onbranch without repository' '
389389
test_must_fail nongit git config get foo.bar
390390
'
391391

392-
test_expect_failure 'onbranch without repository but explicit nonexistent Git directory' '
392+
test_expect_success 'onbranch without repository but explicit nonexistent Git directory' '
393393
test_when_finished "rm -f .gitconfig config.inc" &&
394394
git config set -f .gitconfig "includeIf.onbranch:**.path" config.inc &&
395395
git config set -f config.inc foo.bar baz &&

0 commit comments

Comments
 (0)