From 77cc8e63947243d241af51f8cc95c8b7aaffb00f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 7 Oct 2026 23:04:10 +0200 Subject: [PATCH 1/2] difftool: honor core.symlinks on Windows On Windows, difftool can fail with "Function not implemented" even on NTFS with core.symlinks explicitly enabled. See https://github.com/git-for-windows/git/issues/5517 for context. 8241ae63d821e (difftool: eliminate use of global variables, 2025-02-05) stopped propagating core.symlinks beyond difftool's private setting. The canonical flag checked by mingw_create_symlink() therefore stays false without MSYS=winsymlinks:nativestrict, rejecting creation before CreateSymbolicLinkW() is called. This is a configuration propagation regression, not a filesystem or Developer Mode limitation. Honor the explicit setting consistently without requiring an MSYS override. Assisted-by: GPT-6.1 Signed-off-by: Johannes Schindelin --- builtin/difftool.c | 1 - t/t7800-difftool.sh | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/builtin/difftool.c b/builtin/difftool.c index a08928cb664414..2987a477340249 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -56,7 +56,6 @@ static int difftool_config(const char *var, const char *value, } if (!strcmp(var, "core.symlinks")) { dt_options->has_symlinks = git_config_bool(var, value); - return 0; } return git_default_config(var, value, ctx, cb); diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 40983602b7e9a6..edc33da26dca16 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -645,6 +645,12 @@ test_expect_success SYMLINKS 'difftool --dir-diff --symlinks without unstaged ch test_cmp expect actual ' +test_expect_success MINGW,SYMLINKS 'difftool honors core.symlinks on Windows' ' + test_config difftool.test-tool.cmd "test -L \"\$REMOTE/file\"" && + MSYS= git -c core.symlinks=true difftool --dir-diff \ + --tool=test-tool --trust-exit-code branch HEAD +' + write_script modify-right-file <<\EOF echo "modified content" >"$2/file" EOF From d1e2c7409aa2d967f50f3e062744440f2d5c35f1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 7 Oct 2026 23:50:52 +0200 Subject: [PATCH 2/2] difftool: honor the platform default for symlink support On native Windows, difftool fails with "Function not implemented" when core.symlinks is absent and MSYS is empty. This is another manifestation of https://github.com/git-for-windows/git/issues/5517. 8241ae63d821e (difftool: eliminate use of global variables, 2025-02-05) introduced a private flag initialized to true instead of preserving the platform default. On Windows, the fallback is false unless MSYS contains winsymlinks:nativestrict, so the unconfigured case requests a native symlink that mingw_create_symlink() rejects. Restore the platform default when core.symlinks is unset. Configured values still take precedence, and the non-Windows default remains true. Assisted-by: GPT-6.1 Signed-off-by: Johannes Schindelin --- Documentation/git-difftool.adoc | 4 +++- builtin/difftool.c | 2 +- t/t7800-difftool.sh | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/git-difftool.adoc b/Documentation/git-difftool.adoc index dd7cacf95e35df..5faca9fb91e9c6 100644 --- a/Documentation/git-difftool.adoc +++ b/Documentation/git-difftool.adoc @@ -85,7 +85,9 @@ with custom merge tool commands and has the same value as `$MERGED`. the working tree. + Specifying `--no-symlinks` instructs `git difftool` to create copies -instead. `--no-symlinks` is the default on Windows. +instead. The default follows `core.symlinks`. If unset, native Windows +builds default to copies unless `MSYS=winsymlinks:nativestrict` is set; +other builds default to symlinks. `-x `:: `--extcmd=`:: diff --git a/builtin/difftool.c b/builtin/difftool.c index 2987a477340249..9f60254cac53e5 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -733,7 +733,7 @@ int cmd_difftool(int argc, int use_gui_tool = -1, dir_diff = 0, prompt = -1, tool_help = 0, no_index = 0; static char *difftool_cmd = NULL, *extcmd = NULL; struct difftool_options dt_options = { - .has_symlinks = 1, + .has_symlinks = platform_has_symlinks(), .symlinks = 1, .trust_exit_code = 0 }; diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index edc33da26dca16..f9b18d907078e9 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -651,6 +651,14 @@ test_expect_success MINGW,SYMLINKS 'difftool honors core.symlinks on Windows' ' --tool=test-tool --trust-exit-code branch HEAD ' +test_expect_success MINGW 'difftool defaults to copies on Windows' ' + test_unconfig core.symlinks && + test_config difftool.test-tool.cmd \ + "test -f \"\$REMOTE/file\" && test ! -L \"\$REMOTE/file\"" && + MSYS= git difftool --dir-diff --tool=test-tool --trust-exit-code \ + branch HEAD +' + write_script modify-right-file <<\EOF echo "modified content" >"$2/file" EOF