config: resolve symlinks in conditional include's patterns
$GIT_DIR returned by get_git_dir() is normalized, with all symlinks resolved (see setup_work_tree function). In order to match paths (or patterns) against $GIT_DIR char-by-char, they have to be normalized too. There is a note in config.txt about this, that the user need to resolve symlinks by themselves if needed. The problem is, we allow certain path expansion, '~/' and './', for convenience and can't ask the user to resolve symlinks in these expansions. Make sure the expanded paths have all symlinks resolved. PS. The strbuf_realpath(&text, get_git_dir(), 1) is still needed because get_git_dir() may return relative path. Noticed-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
4aad2f1627
commit
86f9515708
6
config.c
6
config.c
@ -177,7 +177,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
|
|||||||
char *expanded;
|
char *expanded;
|
||||||
int prefix = 0;
|
int prefix = 0;
|
||||||
|
|
||||||
expanded = expand_user_path(pat->buf, 0);
|
expanded = expand_user_path(pat->buf, 1);
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
strbuf_reset(pat);
|
strbuf_reset(pat);
|
||||||
strbuf_addstr(pat, expanded);
|
strbuf_addstr(pat, expanded);
|
||||||
@ -191,7 +191,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
|
|||||||
return error(_("relative config include "
|
return error(_("relative config include "
|
||||||
"conditionals must come from files"));
|
"conditionals must come from files"));
|
||||||
|
|
||||||
strbuf_add_absolute_path(&path, cf->path);
|
strbuf_realpath(&path, cf->path, 1);
|
||||||
slash = find_last_dir_sep(path.buf);
|
slash = find_last_dir_sep(path.buf);
|
||||||
if (!slash)
|
if (!slash)
|
||||||
die("BUG: how is this possible?");
|
die("BUG: how is this possible?");
|
||||||
@ -213,7 +213,7 @@ static int include_by_gitdir(const char *cond, size_t cond_len, int icase)
|
|||||||
struct strbuf pattern = STRBUF_INIT;
|
struct strbuf pattern = STRBUF_INIT;
|
||||||
int ret = 0, prefix;
|
int ret = 0, prefix;
|
||||||
|
|
||||||
strbuf_add_absolute_path(&text, get_git_dir());
|
strbuf_realpath(&text, get_git_dir(), 1);
|
||||||
strbuf_add(&pattern, cond, cond_len);
|
strbuf_add(&pattern, cond, cond_len);
|
||||||
prefix = prepare_include_condition_pattern(&pattern);
|
prefix = prepare_include_condition_pattern(&pattern);
|
||||||
|
|
||||||
|
@ -3,6 +3,16 @@
|
|||||||
test_description='test config file include directives'
|
test_description='test config file include directives'
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
# Force setup_explicit_git_dir() to run until the end. This is needed
|
||||||
|
# by some tests to make sure real_path() is called on $GIT_DIR. The
|
||||||
|
# caller needs to make sure git commands are run from a subdirectory
|
||||||
|
# though or real_path() will not be called.
|
||||||
|
force_setup_explicit_git_dir() {
|
||||||
|
GIT_DIR="$(pwd)/.git"
|
||||||
|
GIT_WORK_TREE="$(pwd)"
|
||||||
|
export GIT_DIR GIT_WORK_TREE
|
||||||
|
}
|
||||||
|
|
||||||
test_expect_success 'include file by absolute path' '
|
test_expect_success 'include file by absolute path' '
|
||||||
echo "[test]one = 1" >one &&
|
echo "[test]one = 1" >one &&
|
||||||
echo "[include]path = \"$(pwd)/one\"" >.gitconfig &&
|
echo "[include]path = \"$(pwd)/one\"" >.gitconfig &&
|
||||||
@ -208,6 +218,50 @@ test_expect_success 'conditional include, both unanchored, icase' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success SYMLINKS 'conditional include, set up symlinked $HOME' '
|
||||||
|
mkdir real-home &&
|
||||||
|
ln -s real-home home &&
|
||||||
|
(
|
||||||
|
HOME="$TRASH_DIRECTORY/home" &&
|
||||||
|
export HOME &&
|
||||||
|
cd "$HOME" &&
|
||||||
|
|
||||||
|
git init foo &&
|
||||||
|
cd foo &&
|
||||||
|
mkdir sub
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success SYMLINKS 'conditional include, $HOME expansion with symlinks' '
|
||||||
|
(
|
||||||
|
HOME="$TRASH_DIRECTORY/home" &&
|
||||||
|
export HOME &&
|
||||||
|
cd "$HOME"/foo &&
|
||||||
|
|
||||||
|
echo "[includeIf \"gitdir:~/foo/\"]path=bar2" >>.git/config &&
|
||||||
|
echo "[test]two=2" >.git/bar2 &&
|
||||||
|
echo 2 >expect &&
|
||||||
|
force_setup_explicit_git_dir &&
|
||||||
|
git -C sub config test.two >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success SYMLINKS 'conditional include, relative path with symlinks' '
|
||||||
|
echo "[includeIf \"gitdir:./foo/.git\"]path=bar4" >home/.gitconfig &&
|
||||||
|
echo "[test]four=4" >home/bar4 &&
|
||||||
|
(
|
||||||
|
HOME="$TRASH_DIRECTORY/home" &&
|
||||||
|
export HOME &&
|
||||||
|
cd "$HOME"/foo &&
|
||||||
|
|
||||||
|
echo 4 >expect &&
|
||||||
|
force_setup_explicit_git_dir &&
|
||||||
|
git -C sub config test.four >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