read-cache: check for leading symlinks when refreshing index

Don't add paths with leading symlinks to the index while refreshing; we only track those symlinks themselves. We already ignore them while preloading (see read_index_preload.c). Reported-by: Nikolay Avdeev <avdeev@math.vsu.ru> Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Aug 9, 2014 at 19:43 UTC ccad42d4836e2bb4d1843eccd94f58f0189abb1d
2 files changed +51
read-cache.c
+8
@@ -1044,6 +1044,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
1044 return ce;
1045 }
1046
1047 + if (has_symlink_leading_path(ce->name, ce_namelen(ce))) {
1048 + if (ignore_missing)
1049 + return ce;
1050 + if (err)
1051 + *err = ENOENT;
1052 + return NULL;
1053 + }
1054 +
1055 if (lstat(ce->name, &st) < 0) {
1056 if (ignore_missing && errno == ENOENT)
1057 return ce;
t/t7515-status-symlinks.sh new
+43
@@ -0,0 +1,43 @@
1 +#!/bin/sh
2 +
3 +test_description='git status and symlinks'
4 +
5 +. ./test-lib.sh
6 +
7 +test_expect_success 'setup' '
8 + echo .gitignore >.gitignore &&
9 + echo actual >>.gitignore &&
10 + echo expect >>.gitignore &&
11 + mkdir dir &&
12 + echo x >dir/file1 &&
13 + echo y >dir/file2 &&
14 + git add dir &&
15 + git commit -m initial &&
16 + git tag initial
17 +'
18 +
19 +test_expect_success SYMLINKS 'symlink to a directory' '
20 + test_when_finished "rm symlink" &&
21 + ln -s dir symlink &&
22 + echo "?? symlink" >expect &&
23 + git status --porcelain >actual &&
24 + test_cmp expect actual
25 +'
26 +
27 +test_expect_success SYMLINKS 'symlink replacing a directory' '
28 + test_when_finished "rm -rf copy && git reset --hard initial" &&
29 + mkdir copy &&
30 + cp dir/file1 copy/file1 &&
31 + echo "changed in copy" >copy/file2 &&
32 + git add copy &&
33 + git commit -m second &&
34 + rm -rf copy &&
35 + ln -s dir copy &&
36 + echo " D copy/file1" >expect &&
37 + echo " D copy/file2" >>expect &&
38 + echo "?? copy" >>expect &&
39 + git status --porcelain >actual &&
40 + test_cmp expect actual
41 +'
42 +
43 +test_done