Merge branch 'rs/refresh-beyond-symlink' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 19 Sep 2014 21:05:11 +0000 (14:05 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 19 Sep 2014 21:05:11 +0000 (14:05 -0700)
* rs/refresh-beyond-symlink:
read-cache: check for leading symlinks when refreshing index

read-cache.c
t/t7515-status-symlinks.sh [new file with mode: 0755]
index 5d3c8bd4aaffda9915a3fd62d9d9800f4ac8baff..6f0057fe66a59e1239703ee4458de200304f727a 100644 (file)
@@ -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 (executable)
index 0000000..9f989be
--- /dev/null
@@ -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