Merge branch 'ab/conditional-config-with-symlinks'
The recently introduced "[includeIf "gitdir:$dir"] path=..." mechansim has further been taught to take symlinks into account. The directory "$dir" specified in "gitdir:$dir" may be a symlink to a real location, not something that $(getcwd) may return. In such a case, a realpath of "$dir" is compared with the real path of the current repository to determine if the contents from the named path should be included. * ab/conditional-config-with-symlinks: config: match both symlink & realpath versions in IncludeIf.gitdir:*
This commit is contained in:
commit
b784d0be5d
@ -145,6 +145,16 @@ A few more notes on matching via `gitdir` and `gitdir/i`:
|
|||||||
|
|
||||||
* Symlinks in `$GIT_DIR` are not resolved before matching.
|
* 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
|
* Note that "../" is not special and will match literally, which is
|
||||||
unlikely what you want.
|
unlikely what you want.
|
||||||
|
|
||||||
|
16
config.c
16
config.c
@ -214,6 +214,7 @@ static int include_by_gitdir(const struct config_options *opts,
|
|||||||
struct strbuf pattern = STRBUF_INIT;
|
struct strbuf pattern = STRBUF_INIT;
|
||||||
int ret = 0, prefix;
|
int ret = 0, prefix;
|
||||||
const char *git_dir;
|
const char *git_dir;
|
||||||
|
int already_tried_absolute = 0;
|
||||||
|
|
||||||
if (opts->git_dir)
|
if (opts->git_dir)
|
||||||
git_dir = 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);
|
strbuf_add(&pattern, cond, cond_len);
|
||||||
prefix = prepare_include_condition_pattern(&pattern);
|
prefix = prepare_include_condition_pattern(&pattern);
|
||||||
|
|
||||||
|
again:
|
||||||
if (prefix < 0)
|
if (prefix < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -245,6 +247,20 @@ static int include_by_gitdir(const struct config_options *opts,
|
|||||||
ret = !wildmatch(pattern.buf + prefix, text.buf + prefix,
|
ret = !wildmatch(pattern.buf + prefix, text.buf + prefix,
|
||||||
icase ? WM_CASEFOLD : 0, NULL);
|
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:
|
done:
|
||||||
strbuf_release(&pattern);
|
strbuf_release(&pattern);
|
||||||
strbuf_release(&text);
|
strbuf_release(&text);
|
||||||
|
@ -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' '
|
test_expect_success 'include cycles are detected' '
|
||||||
cat >.gitconfig <<-\EOF &&
|
cat >.gitconfig <<-\EOF &&
|
||||||
[test]value = gitconfig
|
[test]value = gitconfig
|
||||||
|
Loading…
Reference in New Issue
Block a user