Skip to content

Commit 2935e70

Browse files
t2041: test symlink nested through another symlink
Add a regression test for the grafting fix: a symlink whose target passes through another symlink should still become a directory symlink once its real target appears, even when that target is only populated after the leading symlink has already resolved. Windows path resolution follows a symlink's target regardless of whether it is flagged as a file or directory symlink, so opening a path through it succeeds either way; the type only becomes visible in things like `cmd.exe /c dir`, which marks directory symlinks as <SYMLINKD> and file symlinks as <SYMLINK>. The test asserts on that distinction rather than on read access, since the latter would pass even without the previous commit's fix. Signed-off-by: Chris Harris <chris.harris@discordapp.com>
1 parent a8ed2f6 commit 2935e70

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/sh
2+
3+
test_description='checkout a symlink nested through another symlink on Windows
4+
5+
A phantom symlink may target a path that goes through another
6+
symlink. Ensures that such a symlink is still upgraded to a directory
7+
symlink once its real target appears, even when that target directory
8+
is only populated after the leading symlink has already resolved.'
9+
10+
# Tell MSYS to create native symlinks. Without this flag test-lib's
11+
# prerequisite detection for SYMLINKS doesn't detect the right thing.
12+
MSYS=winsymlinks:nativestrict && export MSYS
13+
14+
. ./test-lib.sh
15+
16+
if ! test_have_prereq MINGW,SYMLINKS
17+
then
18+
skip_all='skipping $0: MinGW-only test, which requires symlink support.'
19+
test_done
20+
fi
21+
22+
# Adds a symlink to the index without clobbering the work tree.
23+
cache_symlink () {
24+
sha=$(printf '%s' "$1" | git hash-object --stdin -w) &&
25+
git update-index --add --cacheinfo 120000,$sha,"$2"
26+
}
27+
28+
# Adds a regular file to the index without clobbering the work tree.
29+
cache_file () {
30+
sha=$(printf '%s' "$1" | git hash-object --stdin -w) &&
31+
git update-index --add --cacheinfo 100644,$sha,"$2"
32+
}
33+
34+
test_expect_success 'symlink nested through another symlink resolves' '
35+
test_when_finished "rm -rf chained" &&
36+
mkdir chained &&
37+
(
38+
cd chained &&
39+
git init -q &&
40+
41+
cache_symlink realdir leading &&
42+
cache_symlink leading/sub nested &&
43+
cache_file content realdir/sub/file &&
44+
45+
git checkout -- . &&
46+
47+
# "cmd.exe /c dir" marks directory symlinks as <SYMLINKD>
48+
# and file symlinks as <SYMLINK>; unlike opening a path
49+
# through the symlink, this distinguishes the two even
50+
# though both resolve identically for plain reads.
51+
cmd.exe //c dir . >dir-listing &&
52+
grep "SYMLINKD.*nested" dir-listing
53+
)
54+
'
55+
56+
test_done

0 commit comments

Comments
 (0)