From 717537daa70d239872176f9a09c1b2539da44fa9 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Nov 2016 09:09:11 -0400 Subject: exclude: do not respect symlinks for in-tree .gitignore 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 Signed-off-by: Junio C Hamano --- dir.c | 9 +++++++-- t/t0008-ignores.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dir.c b/dir.c index 4fa1ca1097..cf3fde0056 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 d27f438bf4..7348b8e6a9 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 -- cgit v1.2.1