Like .gitattributes, we would like to make sure that .gitignore files are handled consistently whether read from the index or from the filesystem. We can do so by using O_NOFOLLOW when opening the files. Signed-off-by: Jeff King <peff@xxxxxxxx> --- dir.c | 9 +++++++-- t/t0008-ignores.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dir.c b/dir.c index 4fa1ca109..cf3fde005 100644 --- a/dir.c +++ b/dir.c @@ -693,6 +693,7 @@ static void invalidate_directory(struct untracked_cache *uc, /* Flags for add_excludes() */ #define EXCLUDE_CHECK_INDEX (1<<0) +#define EXCLUDE_NOFOLLOW (1<<1) /* * Given a file with name "fname", read it (either from disk, or from @@ -713,7 +714,11 @@ static int add_excludes(const char *fname, const char *base, int baselen, size_t size = 0; char *buf, *entry; - fd = open(fname, O_RDONLY); + if (flags & EXCLUDE_NOFOLLOW) + fd = open_nofollow(fname, O_RDONLY); + else + fd = open(fname, O_RDONLY); + if (fd < 0 || fstat(fd, &st) < 0) { if (errno != ENOENT) warn_on_inaccessible(fname); @@ -1130,7 +1135,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen) strbuf_addstr(&sb, dir->exclude_per_dir); el->src = strbuf_detach(&sb, NULL); add_excludes(el->src, el->src, stk->baselen, el, - EXCLUDE_CHECK_INDEX, + EXCLUDE_CHECK_INDEX | EXCLUDE_NOFOLLOW, untracked ? &sha1_stat : NULL); } /* diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index d27f438bf..7348b8e6a 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -841,4 +841,33 @@ test_expect_success 'info/exclude trumps core.excludesfile' ' test_cmp expect actual ' +test_expect_success SYMLINKS 'set up ignore file for symlink tests' ' + echo "*" >ignore +' + +test_expect_success SYMLINKS 'symlinks respected in core.excludesFile' ' + test_when_finished "rm symlink" && + ln -s ignore symlink && + test_config core.excludesFile "$(pwd)/symlink" && + echo file >expect && + git check-ignore file >actual && + test_cmp expect actual +' + +test_expect_success SYMLINKS 'symlinks respected in info/exclude' ' + test_when_finished "rm .git/info/exclude" && + ln -sf ../../ignore .git/info/exclude && + echo file >expect && + git check-ignore file >actual && + test_cmp expect actual +' + +test_expect_success SYMLINKS 'symlinks not respected in-tree' ' + test_when_finished "rm .gitignore" && + ln -sf ignore .gitignore && + >expect && + test_must_fail git check-ignore file >actual && + test_cmp expect actual +' + test_done -- 2.11.0.rc0.258.gf434c15