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 <avd...@math.vsu.ru>
Signed-off-by: Rene Scharfe <l....@web.de>
---
 read-cache.c               |  8 ++++++++
 t/t7515-status-symlinks.sh | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100755 t/t7515-status-symlinks.sh

diff --git a/read-cache.c b/read-cache.c
index 5d3c8bd..6f0057f 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1064,6 +1064,14 @@ static struct cache_entry *refresh_cache_ent(struct 
index_state *istate,
                return ce;
        }
 
+       if (has_symlink_leading_path(ce->name, ce_namelen(ce))) {
+               if (ignore_missing)
+                       return ce;
+               if (err)
+                       *err = ENOENT;
+               return NULL;
+       }
+
        if (lstat(ce->name, &st) < 0) {
                if (ignore_missing && errno == ENOENT)
                        return ce;
diff --git a/t/t7515-status-symlinks.sh b/t/t7515-status-symlinks.sh
new file mode 100755
index 0000000..9f989be
--- /dev/null
+++ b/t/t7515-status-symlinks.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+test_description='git status and symlinks'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo .gitignore >.gitignore &&
+       echo actual >>.gitignore &&
+       echo expect >>.gitignore &&
+       mkdir dir &&
+       echo x >dir/file1 &&
+       echo y >dir/file2 &&
+       git add dir &&
+       git commit -m initial &&
+       git tag initial
+'
+
+test_expect_success SYMLINKS 'symlink to a directory' '
+       test_when_finished "rm symlink" &&
+       ln -s dir symlink &&
+       echo "?? symlink" >expect &&
+       git status --porcelain >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success SYMLINKS 'symlink replacing a directory' '
+       test_when_finished "rm -rf copy && git reset --hard initial" &&
+       mkdir copy &&
+       cp dir/file1 copy/file1 &&
+       echo "changed in copy" >copy/file2 &&
+       git add copy &&
+       git commit -m second &&
+       rm -rf copy &&
+       ln -s dir copy &&
+       echo " D copy/file1" >expect &&
+       echo " D copy/file2" >>expect &&
+       echo "?? copy" >>expect &&
+       git status --porcelain >actual &&
+       test_cmp expect actual
+'
+
+test_done
-- 
2.0.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to