aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-12-18 08:20:25 +0900
committerJunio C Hamano <gitster@pobox.com>2025-12-18 08:20:25 +0900
commit3d86511c12a6136d57fadea7638630550a6deeac (patch)
tree1346325386b1babd8fd4b4495d788a9198d31367
parente7ef0ca622016d12a85836928a03959de4537c2f (diff)
parentef6dd000ad813fc34a05c4b9055578df13a2eaa6 (diff)
downloadgit-3d86511c12a6136d57fadea7638630550a6deeac.tar.xz
Merge branch 'js/test-symlink-windows' into js/prep-symlink-windows
* js/test-symlink-windows: t7800: work around the MSYS path conversion on Windows t6423: introduce Windows-specific handling for symlinking to /dev/null t1305: skip symlink tests that do not apply to Windows t1006: accommodate for symlink support in MSYS2 t0600: fix incomplete prerequisite for a test case t0301: another fix for Windows compatibility t0001: handle `diff --no-index` gracefully mingw: special-case `open(symlink, O_CREAT | O_EXCL)` apply: symbolic links lack a "trustable executable bit" t9700: accommodate for Windows paths
-rw-r--r--apply.c2
-rw-r--r--compat/mingw.c14
-rwxr-xr-xt/t0001-init.sh6
-rwxr-xr-xt/t0301-credential-cache.sh3
-rwxr-xr-xt/t0600-reffiles-backend.sh2
-rwxr-xr-xt/t1006-cat-file.sh24
-rwxr-xr-xt/t1305-config-include.sh4
-rwxr-xr-xt/t6423-merge-rename-directories.sh9
-rwxr-xr-xt/t7800-difftool.sh8
-rwxr-xr-xt/t9700/test.pl9
10 files changed, 60 insertions, 21 deletions
diff --git a/apply.c b/apply.c
index c9fb45247d..3de4aa4d2e 100644
--- a/apply.c
+++ b/apply.c
@@ -3818,7 +3818,7 @@ static int check_preimage(struct apply_state *state,
if (*ce && !(*ce)->ce_mode)
BUG("ce_mode == 0 for path '%s'", old_name);
- if (trust_executable_bit)
+ if (trust_executable_bit || !S_ISREG(st->st_mode))
st_mode = ce_mode_from_stat(*ce, st->st_mode);
else if (*ce)
st_mode = (*ce)->ce_mode;
diff --git a/compat/mingw.c b/compat/mingw.c
index 939f938fe2..f09b49ff21 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -629,6 +629,7 @@ int mingw_open (const char *filename, int oflags, ...)
int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
wchar_t wfilename[MAX_PATH];
open_fn_t open_fn;
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
@@ -653,6 +654,19 @@ int mingw_open (const char *filename, int oflags, ...)
else if (xutftowcs_path(wfilename, filename) < 0)
return -1;
+ /*
+ * When `symlink` exists and is a symbolic link pointing to a
+ * non-existing file, `_wopen(symlink, O_CREAT | O_EXCL)` would
+ * create that file. Not what we want: Linux would say `EEXIST`
+ * in that instance, which is therefore what Git expects.
+ */
+ if (create &&
+ GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata) &&
+ (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ errno = EEXIST;
+ return -1;
+ }
+
fd = open_fn(wfilename, oflags, mode);
/*
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 618da080dc..e4d32bb4d2 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -425,7 +425,11 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
git init --separate-git-dir ../realgitdir
) &&
echo "gitdir: $(pwd)/realgitdir" >expected &&
- test_cmp expected newdir/.git &&
+ case "$GIT_TEST_CMP" in
+ # `git diff --no-index` does not resolve symlinks
+ *--no-index*) cmp expected newdir/.git;;
+ *) test_cmp expected newdir/.git;;
+ esac &&
test_cmp expected newdir/here &&
test_path_is_dir realgitdir/refs
'
diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
index dc30289f75..6f7cfd9e33 100755
--- a/t/t0301-credential-cache.sh
+++ b/t/t0301-credential-cache.sh
@@ -123,7 +123,8 @@ test_expect_success SYMLINKS 'use user socket if user directory is a symlink to
rmdir \"\$HOME/dir/\" &&
rm \"\$HOME/.git-credential-cache\"
" &&
- mkdir -p -m 700 "$HOME/dir/" &&
+ mkdir -p "$HOME/dir/" &&
+ chmod 700 "$HOME/dir/" &&
ln -s "$HOME/dir" "$HOME/.git-credential-cache" &&
check approve cache <<-\EOF &&
protocol=https
diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh
index b11126ed47..74bfa2e9ba 100755
--- a/t/t0600-reffiles-backend.sh
+++ b/t/t0600-reffiles-backend.sh
@@ -467,7 +467,7 @@ test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' '
esac
'
-test_expect_success SYMLINKS 'symref transaction supports symlinks' '
+test_expect_success SYMLINKS,!MINGW 'symref transaction supports symlinks' '
test_when_finished "git symbolic-ref -d TEST_SYMREF_HEAD" &&
git update-ref refs/heads/new @ &&
test_config core.prefersymlinkrefs true &&
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 1f61b666a7..0eee3bb878 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -1048,18 +1048,28 @@ test_expect_success 'git cat-file --batch-check --follow-symlinks works for out-
echo .. >>expect &&
echo HEAD:dir/subdir/out-of-repo-link-dir | git cat-file --batch-check --follow-symlinks >actual &&
test_cmp expect actual &&
- echo symlink 3 >expect &&
- echo ../ >>expect &&
+ if test_have_prereq MINGW,SYMLINKS
+ then
+ test_write_lines "symlink 2" ..
+ else
+ test_write_lines "symlink 3" ../
+ fi >expect &&
echo HEAD:dir/subdir/out-of-repo-link-dir-trailing | git cat-file --batch-check --follow-symlinks >actual &&
test_cmp expect actual
'
test_expect_success 'git cat-file --batch-check --follow-symlinks works for symlinks with internal ..' '
- echo HEAD: | git cat-file --batch-check >expect &&
- echo HEAD:up-down | git cat-file --batch-check --follow-symlinks >actual &&
- test_cmp expect actual &&
- echo HEAD:up-down-trailing | git cat-file --batch-check --follow-symlinks >actual &&
- test_cmp expect actual &&
+ if test_have_prereq !MINGW
+ then
+ # The `up-down` and `up-down-trailing` symlinks are normalized
+ # in MSYS in `winsymlinks` mode and are therefore in a
+ # different shape than Git expects them.
+ echo HEAD: | git cat-file --batch-check >expect &&
+ echo HEAD:up-down | git cat-file --batch-check --follow-symlinks >actual &&
+ test_cmp expect actual &&
+ echo HEAD:up-down-trailing | git cat-file --batch-check --follow-symlinks >actual &&
+ test_cmp expect actual
+ fi &&
echo HEAD:up-down-file | git cat-file --batch-check --follow-symlinks >actual &&
test_cmp found actual &&
echo symlink 7 >expect &&
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index 8ff2b0c232..6e51f892f3 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -286,7 +286,7 @@ test_expect_success SYMLINKS 'conditional include, relative path with symlinks'
)
'
-test_expect_success SYMLINKS 'conditional include, gitdir matching symlink' '
+test_expect_success SYMLINKS,!MINGW 'conditional include, gitdir matching symlink' '
ln -s foo bar &&
(
cd bar &&
@@ -298,7 +298,7 @@ test_expect_success SYMLINKS 'conditional include, gitdir matching symlink' '
)
'
-test_expect_success SYMLINKS 'conditional include, gitdir matching symlink, icase' '
+test_expect_success SYMLINKS,!MINGW 'conditional include, gitdir matching symlink, icase' '
(
cd bar &&
echo "[includeIf \"gitdir/i:BAR/\"]path=bar8" >>.git/config &&
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 533ac85dc8..53535a8ebf 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -5158,13 +5158,18 @@ test_setup_12m () {
git switch B &&
git rm dir/subdir/file &&
mkdir dir &&
- ln -s /dev/null dir/subdir &&
+ if test_have_prereq MINGW
+ then
+ cmd //c 'mklink dir\subdir NUL'
+ else
+ ln -s /dev/null dir/subdir
+ fi &&
git add . &&
git commit -m "B"
)
}
-test_expect_success '12m: Change parent of renamed-dir to symlink on other side' '
+test_expect_success SYMLINKS '12m: Change parent of renamed-dir to symlink on other side' '
test_setup_12m &&
(
cd 12m &&
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 9b74db5563..bf0f67378d 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -752,11 +752,11 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
c
EOF
git difftool --symlinks --dir-diff --extcmd ls >output &&
- grep -v ^/ output >actual &&
+ grep -v ":\$" output >actual &&
test_cmp expect actual &&
git difftool --no-symlinks --dir-diff --extcmd ls >output &&
- grep -v ^/ output >actual &&
+ grep -v ":\$" output >actual &&
test_cmp expect actual &&
# The left side contains symlink "c" that points to "b"
@@ -786,11 +786,11 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
EOF
git difftool --symlinks --dir-diff --extcmd ls >output &&
- grep -v ^/ output >actual &&
+ grep -v ":\$" output >actual &&
test_cmp expect actual &&
git difftool --no-symlinks --dir-diff --extcmd ls >output &&
- grep -v ^/ output >actual &&
+ grep -v ":\$" output >actual &&
test_cmp expect actual
'
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 58a9b328d5..570b0c5680 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -117,7 +117,12 @@ close TEMPFILE;
unlink $tmpfile;
# paths
-is($r->repo_path, $abs_repo_dir . "/.git", "repo_path");
+my $abs_git_dir = $abs_repo_dir . "/.git";
+if ($^O eq 'msys' or $^O eq 'cygwin') {
+ $abs_git_dir = `cygpath -am "$abs_repo_dir/.git"`;
+ $abs_git_dir =~ s/\r?\n?$//;
+}
+is($r->repo_path, $abs_git_dir, "repo_path");
is($r->wc_path, $abs_repo_dir . "/", "wc_path");
is($r->wc_subdir, "", "wc_subdir initial");
$r->wc_chdir("directory1");
@@ -127,7 +132,7 @@ is($r->config("test.string"), "value", "config after wc_chdir");
# Object generation in sub directory
chdir("directory2");
my $r2 = Git->repository();
-is($r2->repo_path, $abs_repo_dir . "/.git", "repo_path (2)");
+is($r2->repo_path, $abs_git_dir, "repo_path (2)");
is($r2->wc_path, $abs_repo_dir . "/", "wc_path (2)");
is($r2->wc_subdir, "directory2/", "wc_subdir initial (2)");