You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
error: could not symlink 'path1' to 'path2': Function not implemented #5517
Thank you for filling out a Git bug report!
Please answer the following questions to help us understand your issue.
What did you do before the bug happened? (Steps to reproduce your issue)
I was trying to do a normal `git difftool -gd hash1 hash2` -- this used to work perfectly.
What did you expect to happen? (Expected behavior)
BC4 (Beyond Compare 4) to launch in a directory-comparison session comparing the 2 commits.
What happened instead? (Actual behavior)
This:
$ git difftool -gd d604180 fc16efc
error: could not symlink 'E:/Dev/Clients/WGA/lvgl/vwheeler63/lvgl/docs/src/details/main-modules/draw/draw_descriptors.rst' to 'R:\TMPDIR/git-difftool.a04204/right/docs/src/details/main-modules/draw/draw_descriptors.rst': Function not implemented
I don't often need this, but when I do, I really need it, and I think it worked
perfectly 4-5 months ago (last time I did it). (My memory on this timing is
vague—it might have been as much as 7 months ago.)
What's different between what you expected and what actually happened?
Instead of launching BC4, it issued this error message.
Anything else you want to add:
I'm using mintty on a Windows 10 x64 system (up to date as of today's date).
Please review the rest of the bug report below.
You can delete any lines you don't wish to share.
[System Info]
git version:
git version 2.48.1.windows.1
cpu: x86_64
built from commit: 2bd190b
sizeof-long: 4
sizeof-size_t: 8
shell-path: D:/git-sdk-64-build-installers/usr/bin/sh
<<<< Note: the above is a bit odd because I don't have a `D:` drive and no
removable drive was mounted as `D:` when I executed `git bugreport` to gather
this text. In case it helps, the above `git difftool -gd` command was issued while
the `E:` drive was the current drive, but I have never had trouble with it before,
and have been using this command for years -- at least since 2018 with zero problems.
feature: fsmonitor--daemon
libcurl: 8.12.1
OpenSSL: OpenSSL 3.2.4 11 Feb 2025
zlib: 1.3.1
uname: Windows 10.0 19045
compiler info: gnuc: 14.2
libc info: no libc information available
$SHELL (typically, interactive shell): C:\Program Files\Git\usr\bin\bash.exe
E: is an SD drive -- NTFS -- it is a separate drive where I do most of my work it can be incrementally backed up every night, unlike my C: drive which doesn't change that often.
R: is a RAMDISK -- FAT32 -- used to save wear-and-tear on my SD drives. I have had this configuration since 2012, and it has been working for git difftool -gd hash1 hash2 since I started using git in 2018.
E: is an SD drive -- it is a separate drive so that it can be fully (incrementally) backed up every night.
I was less concerned about the underlying hardware, but how it was formatted (ReFS, FAT32, NTFS, ...), and in the case of R:\ wether it poentially was a ram disk, network share or something similar.
I'm glad there is a workaround. As a note (in case the git-scm team wasn't already aware of it): on this page: https://git-scm.com/docs/git-difftool it says:
... --no-symlinks is the default on Windows.
so it would appear that documentation is out of sync with the executable? Or vice versa?
<<<< Note: the above is a bit odd because I don't have a `D:` drive and no
removable drive was mounted as `D:` when I executed `git bugreport` to gather
this text. In case it helps, the above `git difftool -gd` command was issued while
the `E:` drive was the current drive, but I have never had trouble with it before,
and have been using this command for years -- at least since 2018 with zero problems.
@vwheeler63 this information is unfortunately a bit misleading. I am not a fan of the git bugreport command, and this is one of the reasons: What it shows here are not the runtime settings, but the compile-time settings. The shell-path in particular does not affect how Git for Windows runs, as it will determine the path of the shell interpreter dynamically.
Also, is there any reason why you marked up your reply, not the output of git bugreport, as code (by prefixing/suffixing it with lines containing four backticks)? It's just a bit harder to read when marked up this way, my eyes stumbled over this.
so it would appear that documentation is out of sync with the executable?
This note was introduced in 1f22934, when the statement was true.
However, when I converted this command from a Perl script (!) to a built-in written in portable C in 03831ef, I changed that to respect the core.symlinks variable, which is set by git init/git clonedepending on the outcome of a simple test.
What core.symlinks does not do is to verify that symlinks are supported outside the worktree, and that includes the TMPDIR.
In the long run, I am fairly convinced you will want to reformat your RAM disk using ReFS (or NTFS), to avoid similar problems.
Having said that, the regression in 8241ae6 is real and needs to be addressed.
I have had this configuration since 2012, and it has been working for git difftool -gd hash1 hash2 since I started using git in 2018.
Now, this is curious. The core.symlinks of your worktree on the E: drive should be set to true, because you're using uname: Windows 10.0 19045 and that already supports symlink creation in Developer Mode. Or are you not running in Developer Mode?
I am not a fan of the git bugreport command, and this is one of the reasons: What it shows here are not the runtime settings, but the compile-time settings.
Ah! That explains that. Thank you.
...is there any reason why you marked up your reply, not the output of git bugreport, as code (by prefixing/suffixing it with lines containing four backticks)? It's just a bit harder to read when marked up this way, my eyes stumbled over this.
Fair question: my only intent was to indent the paragraph so that it showed I was commenting about the line above it. The 4 backticks was unintentional (I intended 3, and in retrospect, could merely have indented the paragraph—and the fact that the 4 backticks appeared twice was probably a copy-paste casualty).
What core.symlinks does not do is to verify that symlinks are supported outside the worktree, and that includes the TMPDIR.
That makes sense and is good to know. It also makes sense to do the test once and keep the result as a repository-configuration value—as opposed to doing the test with every command, if only for sake of limiting how often that overhead is incurred. (It's also quite orienting to see that in the C code [since I am just getting familiar with the project]. Thank you for that.)
In the long run, I am fairly convinced you will want to reformat your RAM disk using ReFS (or NTFS), to avoid similar problems.
In fact I thought about it, but decided against it. Reason: I have the RAM disk there and configured the way it is (FAT32 + Direct-IO access as opposed to through a SCSI driver) for speed. (Reason: I do a large amount of small-file generation and deletion every day [including web-browser caches] there to reduce wear-and-tear on my SD drives.) If being able to use symlinks was my priority, I would certainly use NTFS. (Even the newest version of my RAM disk software doesn't yet know about ReFS.) Though I will humbly admit: I do not know if I would notice the difference using NTFS.... **rolling eyes at self** Probably not.
Since there is no wear-and-tear concerns with doing actual file copies on a RAMDisk (as there is with SD drives), for now I will set a global core.symlinks configuration to false.
Having said that, the regression in 8241ae6 is real and needs to be addressed.
I'm thankful for that.
Now, this is curious. The core.symlinks of your worktree on the E: drive should be set to true, because you're using uname: Windows 10.0 19045 and that already supports symlink creation in Developer Mode. Or are you not running in Developer Mode?
I am indeed running in Developer Mode.
On a hunch, I went to look at the repository where I was working the last time I used git difftool -g --dir-diff and sure enough: core.symlinks = false, was set local to that repository. (I created the repository first locally [as opposed to cloning it], so I must have set it myself.) That explains why it worked (for me) previously and not yesterday (in a different repository, cloned, where core.symlinks is not set locally).
In Conclusion
I am happy to set a global core.symlinks configuration to false while I have this TEMP environment variable set to my RAM disk.
I just tried it and indeed, difftool is now working as it was before. 😄 (I have to say, I think difftool is one of the most powerful features of git!)
I encountered this problem as well. difftool works fine in 2.48.1 but no longer works in 2.49.0.
This could also be related to 84f0bdc. git difftool uses the new create_symlink() when core.symlinks is set to true (difftool.c#L544). Maybe something in the change from symlink() to create_symlink() caused this problem?
eta: in my case, I'm on Windows 11, and my repository and my TEMP directory are both on C:, which uses NTFS. On 2.48.1, difftool -d --symlinks works works correctly.
Ah... I saw the "2 weeks ago" in the commit I linked and assumed it was new. My bad.
In that case, I don't see why I'm getting different behaviors between 2.48.1 and 2.49.0, considering symlinks seem to be supported just fine when using 2.48.1.
I performed some more extensive tests, here are the differences between 2.48.1 and 2.49.0.
Using Windows 11 Pro 24H2, build 26100.3476.
Git was installed using choco install git --version=[version], and version was confirmed using git --version.
core.symlinks is always explicitly specified in my user .gitconfig file, and never in my local repository's .git/config file.
I ran git difftool -d [symlinks flag] master... for each of the following tests.
All failures have the same error message: "error: could not symlink '[path in repo]' to '[path in %TEMP%]': Function not implemented."
In short, it looks like no matter what, 2.49.0 is unable to create symlinks for difftool. I also find it interesting that both versions are unable to create symlinks for difftool when core.symlinks is false, as I would expect that to only affect the behaviour for symlinks in repositories.
core.symlinks
symlinks flag
Using Git 2.48.1
Using Git 2.49.0
false
[not specified]
Creates copies
Creates copies
false
--no-symlinks
Creates copies
Creates copies
false
--symlinks
Fails
Fails
true
[not specified]
Creates symlinks
Fails
true
--no-symlinks
Creates copies
Creates copies
true
--symlinks
Creates symlinks
Fails
(p.s. after reading through the prior discussions, I understand this isn't the same as the original problem reported by @vwheeler63, I just happened to get a similar error message on the same day 😅 )
Reacted by Victor Wheeler, Nick Guerrera, Jason Holmes, hlovdal and Bart Joy
I too had difftool break with 2.49 on NTFS drives with core.symlinks=true globally and locally. This is my first time poking around in the code, so I'm not confident on the fix (especially since it overlaps test suite practices) but I can at least point to the apparent root cause.
The error is coming straight from mingw_create_symlink() in /compat/mingw.c:
/* fail if symlinks are disabled or API is not supported (WinXP) */
if (!has_symlinks) {
errno = ENOSYS;
return -1;
}
The ENOSYS is giving you "Function not implemented".
The erroneous has_symlinks value is coming from mingw startup setup_windows_environment(), also in /compat/mingw.c:
/*
* Change 'core.symlinks' default to false, unless native symlinks are
* enabled in MSys2 (via 'MSYS=winsymlinks:nativestrict'). Thus we can
* run the test suite (which doesn't obey config files) with or without
* symlink support.
*/
if (!(tmp = getenv("MSYS")) || !strstr(tmp, "winsymlinks:nativestrict"))
has_symlinks = 0;
But the git_default_config lookup of core.symlinks already sets has_symlinks=1, which meets the intent that users have to explicitly opt into symlink support. The result of the above is to disable it for everything but the test code.
If the default needs to be false, then maybe the fix is to update the initialization of the has_symlinks global variable (currently it's set to 1), and then change the above code to invert and enable it for the test suite.
Reacted by Nick Guerrera, vec4f, Martin Boisvert, Zeev Rotshtein and Bart Joy
I also just got it after updating to 2.51.0. Unfortunately, I don't recall the exact version I had prior to updating. Regardless, it has always worked until I updated. I verified in PowerShell 7.5 and Git Bash. I have core.symlinks=true in my .gitconfig and nothing changed in it for weeks. Beyond Compare 4 is my difftool and configured to follow symlinks (nothing changed here, either). Entirely on my C:\ drive, which is NTFS. Developer Mode is enabled. Same bug on all repos. Setting this in PowerShell $env:MSYS = "winsymlinks:nativestrict" THEN running git difftool --dir-diff --staged allows it to work again. I guess I can just set that environment variable for now. Should that be considered a temporary work around, or a permanent/required environment variable moving forward?
While the work-around described above is still working, in this comment you mentioned there was a regression in commit 8241ae6 . Are you aware whether this is anywhere on the radar to be addressed?
This issue still exists in the latest version. The workaround still works. I see people have already pointed out the commit that caused the bug. Would love to see it fixed.
Activity
rimrul commentedon Mar 27, 2025
I assume you
%TEMP%points toR:\TMPDIR?What filesystems are
E:\andR:\?vwheeler63 commentedon Mar 27, 2025
That is correct.
E:is an SD drive -- NTFS -- it is a separate drive where I do most of my work it can be incrementally backed up every night, unlike my C: drive which doesn't change that often.R:is a RAMDISK -- FAT32 -- used to save wear-and-tear on my SD drives. I have had this configuration since 2012, and it has been working forgit difftool -gd hash1 hash2since I started usinggitin 2018.rimrul commentedon Mar 27, 2025
I was less concerned about the underlying hardware, but how it was formatted (ReFS, FAT32, NTFS, ...), and in the case of
R:\wether it poentially was a ram disk, network share or something similar.I had a sneaking suspicion it might be.
vwheeler63 commentedon Mar 27, 2025
E: NTFS
R: FAT32
rimrul commentedon Mar 27, 2025
Looking at 8241ae6#diff-34f226145d3399ac034db4d76355be47bd76a6b919058929124d82461205d11fL707-R722, it looks like the default for
--symlinkswas flipped in 2.49.0. andFAT32doesn't support symlinks. you can probably work around that with--no-symlinksfor now.vwheeler63 commentedon Mar 27, 2025
I'm glad there is a workaround. As a note (in case the git-scm team wasn't already aware of it): on this page: https://git-scm.com/docs/git-difftool it says:
so it would appear that documentation is out of sync with the executable? Or vice versa?
dscho commentedon Mar 28, 2025
@vwheeler63 this information is unfortunately a bit misleading. I am not a fan of the
git bugreportcommand, and this is one of the reasons: What it shows here are not the runtime settings, but the compile-time settings. Theshell-pathin particular does not affect how Git for Windows runs, as it will determine the path of theshellinterpreter dynamically.Also, is there any reason why you marked up your reply, not the output of
git bugreport, as code (by prefixing/suffixing it with lines containing four backticks)? It's just a bit harder to read when marked up this way, my eyes stumbled over this.This note was introduced in 1f22934, when the statement was true.
However, when I converted this command from a Perl script (!) to a built-in written in portable C in 03831ef, I changed that to respect the
core.symlinksvariable, which is set bygit init/git clonedepending on the outcome of a simple test.What
core.symlinksdoes not do is to verify that symlinks are supported outside the worktree, and that includes theTMPDIR.In the long run, I am fairly convinced you will want to reformat your RAM disk using ReFS (or NTFS), to avoid similar problems.
Having said that, the regression in 8241ae6 is real and needs to be addressed.
Now, this is curious. The
core.symlinksof your worktree on theE:drive should be set totrue, because you're usinguname: Windows 10.0 19045and that already supports symlink creation in Developer Mode. Or are you not running in Developer Mode?vwheeler63 commentedon Mar 28, 2025
Hi, Johannes! I'm honored to speak with you!
Ah! That explains that. Thank you.
Fair question: my only intent was to indent the paragraph so that it showed I was commenting about the line above it. The 4 backticks was unintentional (I intended 3, and in retrospect, could merely have indented the paragraph—and the fact that the 4 backticks appeared twice was probably a copy-paste casualty).
That makes sense and is good to know. It also makes sense to do the test once and keep the result as a repository-configuration value—as opposed to doing the test with every command, if only for sake of limiting how often that overhead is incurred. (It's also quite orienting to see that in the C code [since I am just getting familiar with the project]. Thank you for that.)
In fact I thought about it, but decided against it. Reason: I have the RAM disk there and configured the way it is (FAT32 + Direct-IO access as opposed to through a SCSI driver) for speed. (Reason: I do a large amount of small-file generation and deletion every day [including web-browser caches] there to reduce wear-and-tear on my SD drives.) If being able to use symlinks was my priority, I would certainly use NTFS. (Even the newest version of my RAM disk software doesn't yet know about ReFS.) Though I will humbly admit: I do not know if I would notice the difference using NTFS....
**rolling eyes at self**Probably not.Since there is no wear-and-tear concerns with doing actual file copies on a RAMDisk (as there is with SD drives), for now I will set a global
core.symlinksconfiguration tofalse.I'm thankful for that.
I am indeed running in Developer Mode.
On a hunch, I went to look at the repository where I was working the last time I used
git difftool -g --dir-diffand sure enough:core.symlinks = false, was set local to that repository. (I created the repository first locally [as opposed to cloning it], so I must have set it myself.) That explains why it worked (for me) previously and not yesterday (in a different repository, cloned, wherecore.symlinksis not set locally).In Conclusion
I am happy to set a global
core.symlinksconfiguration tofalsewhile I have this TEMP environment variable set to my RAM disk.I just tried it and indeed,
difftoolis now working as it was before. 😄 (I have to say, I thinkdifftoolis one of the most powerful features ofgit!)vwheeler63 commentedon Mar 28, 2025
Are there good reasons I have not yet thought of to reconsider using NTFS on my RAM drive?
(I was fascinated reading the commit message on 03831ef! Thank you for sharing that.)
boimart1 commentedon Mar 28, 2025
I encountered this problem as well.
difftoolworks fine in 2.48.1 but no longer works in 2.49.0.This could also be related to 84f0bdc.
git difftooluses the newcreate_symlink()whencore.symlinksis set to true (difftool.c#L544). Maybe something in the change fromsymlink()tocreate_symlink()caused this problem?eta: in my case, I'm on Windows 11, and my repository and my TEMP directory are both on
C:, which uses NTFS. On 2.48.1,difftool -d --symlinksworks works correctly.rimrul commentedon Mar 28, 2025
create_symlink()is from 2019. https://github.com/git-for-windows/git/commit/51540f330c1/ It's really not that new.boimart1 commentedon Mar 28, 2025
Ah... I saw the "2 weeks ago" in the commit I linked and assumed it was new. My bad.
In that case, I don't see why I'm getting different behaviors between 2.48.1 and 2.49.0, considering symlinks seem to be supported just fine when using 2.48.1.
boimart1 commentedon Mar 28, 2025
I performed some more extensive tests, here are the differences between 2.48.1 and 2.49.0.
choco install git --version=[version], and version was confirmed usinggit --version.core.symlinksis always explicitly specified in my user.gitconfigfile, and never in my local repository's.git/configfile.git difftool -d [symlinks flag] master...for each of the following tests.In short, it looks like no matter what, 2.49.0 is unable to create symlinks for difftool. I also find it interesting that both versions are unable to create symlinks for difftool when core.symlinks is false, as I would expect that to only affect the behaviour for symlinks in repositories.
(p.s. after reading through the prior discussions, I understand this isn't the same as the original problem reported by @vwheeler63, I just happened to get a similar error message on the same day 😅 )
mababey commentedon Apr 16, 2025
I too had difftool break with 2.49 on NTFS drives with core.symlinks=true globally and locally. This is my first time poking around in the code, so I'm not confident on the fix (especially since it overlaps test suite practices) but I can at least point to the apparent root cause.
The error is coming straight from
mingw_create_symlink()in /compat/mingw.c:The ENOSYS is giving you "Function not implemented".
The erroneous
has_symlinksvalue is coming from mingw startupsetup_windows_environment(), also in /compat/mingw.c:But the
git_default_configlookup of core.symlinks already setshas_symlinks=1, which meets the intent that users have to explicitly opt into symlink support. The result of the above is to disable it for everything but the test code.If the default needs to be false, then maybe the fix is to update the initialization of the
has_symlinksglobal variable (currently it's set to 1), and then change the above code to invert and enable it for the test suite.djneades commentedon May 6, 2025
We are running into this, too. In PowerShell, running
$Env:MSYS="winsymlinks:nativestrict"does appear to work around the problem.cmconti commentedon May 19, 2025
I believe I've seen a similar issue:
details in general git mailing list here (sorry I missed this thread before I posted over there)
setting
winsymlinks:nativestrictin the MSYS env var also fixes the issuesasha2048 commentedon Jun 6, 2025
Same for me:
MSYSenv var towinsymlinks:nativestricthelpszeevro commentedon Aug 11, 2025
Same for me:
KyleKolander commentedon Aug 30, 2025
I also just got it after updating to 2.51.0. Unfortunately, I don't recall the exact version I had prior to updating. Regardless, it has always worked until I updated. I verified in PowerShell 7.5 and Git Bash. I have
core.symlinks=truein my.gitconfigand nothing changed in it for weeks. Beyond Compare 4 is my difftool and configured to follow symlinks (nothing changed here, either). Entirely on my C:\ drive, which is NTFS. Developer Mode is enabled. Same bug on all repos. Setting this in PowerShell$env:MSYS = "winsymlinks:nativestrict"THEN runninggit difftool --dir-diff --stagedallows it to work again. I guess I can just set that environment variable for now. Should that be considered a temporary work around, or a permanent/required environment variable moving forward?vwheeler63 commentedon Aug 30, 2025
Good afternoon, @dscho !
While the work-around described above is still working, in this comment you mentioned there was a regression in commit 8241ae6 . Are you aware whether this is anywhere on the radar to be addressed?
Kind regards,
Vic
difftool: let core.symlinks update the global has_symlinks
difftool: let core.symlinks update the global has_symlinks
niwazukihon commentedon Sep 26, 2026
This issue still exists in the latest version. The workaround still works. I see people have already pointed out the commit that caused the bug. Would love to see it fixed.
djneades commentedon Oct 7, 2026
This problem occurs on machines with Developer Mode on.
dscho commentedon Oct 7, 2026
@djneades you probably understand that you were talking to a Claw?
dscho commentedon Oct 7, 2026
Y'all, I opened #6468 and let it build a tentative snapshot at https://github.com/git-for-windows/git-for-windows-automation/actions/runs/37696201592. Once that's done (hopefully successful), could you test the
portablebuild artifact to see whether it really fixes the issue?dscho commentedon Oct 8, 2026
@djneades @niwazukihon here are the Portable Git snapshots: x64 and arm64. Could you please test?
djneades commentedon Oct 9, 2026
@dscho I briefly tested your new build (x64) and it does indeed look like it fixes the issue. Thank you!