diff options
-rw-r--r-- | Documentation/config.txt | 10 | ||||
-rw-r--r-- | config.c | 16 | ||||
-rwxr-xr-x | t/t1305-config-include.sh | 23 |
3 files changed, 49 insertions, 0 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 475e874d51..302b8af192 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -140,6 +140,16 @@ A few more notes on matching via `gitdir` and `gitdir/i`: * Symlinks in `$GIT_DIR` are not resolved before matching. + * Both the symlink & realpath versions of paths will be matched + outside of `$GIT_DIR`. E.g. if ~/git is a symlink to + /mnt/storage/git, both `gitdir:~/git` and `gitdir:/mnt/storage/git` + will match. ++ +This was not the case in the initial release of this feature in +v2.13.0, which only matched the realpath version. Configuration that +wants to be compatible with the initial release of this feature needs +to either specify only the realpath version, or both versions. + * Note that "../" is not special and will match literally, which is unlikely what you want. @@ -214,6 +214,7 @@ static int include_by_gitdir(const struct config_options *opts, struct strbuf pattern = STRBUF_INIT; int ret = 0, prefix; const char *git_dir; + int already_tried_absolute = 0; if (opts->git_dir) git_dir = opts->git_dir; @@ -226,6 +227,7 @@ static int include_by_gitdir(const struct config_options *opts, strbuf_add(&pattern, cond, cond_len); prefix = prepare_include_condition_pattern(&pattern); +again: if (prefix < 0) goto done; @@ -245,6 +247,20 @@ static int include_by_gitdir(const struct config_options *opts, ret = !wildmatch(pattern.buf + prefix, text.buf + prefix, icase ? WM_CASEFOLD : 0, NULL); + if (!ret && !already_tried_absolute) { + /* + * We've tried e.g. matching gitdir:~/work, but if + * ~/work is a symlink to /mnt/storage/work + * strbuf_realpath() will expand it, so the rule won't + * match. Let's match against a + * strbuf_add_absolute_path() version of the path, + * which'll do the right thing + */ + strbuf_reset(&text); + strbuf_add_absolute_path(&text, git_dir); + already_tried_absolute = 1; + goto again; + } done: strbuf_release(&pattern); strbuf_release(&text); diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index 933915ec06..d9d2f545a4 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -273,6 +273,29 @@ test_expect_success SYMLINKS 'conditional include, relative path with symlinks' ) ' +test_expect_success SYMLINKS 'conditional include, gitdir matching symlink' ' + ln -s foo bar && + ( + cd bar && + echo "[includeIf \"gitdir:bar/\"]path=bar7" >>.git/config && + echo "[test]seven=7" >.git/bar7 && + echo 7 >expect && + git config test.seven >actual && + test_cmp expect actual + ) +' + +test_expect_success SYMLINKS 'conditional include, gitdir matching symlink, icase' ' + ( + cd bar && + echo "[includeIf \"gitdir/i:BAR/\"]path=bar8" >>.git/config && + echo "[test]eight=8" >.git/bar8 && + echo 8 >expect && + git config test.eight >actual && + test_cmp expect actual + ) +' + test_expect_success 'include cycles are detected' ' cat >.gitconfig <<-\EOF && [test]value = gitconfig |