Symlinks in Windows, MinGW, Git, and Cygwin19 Jan 2018
Symlinks are a commonly used feature in Linux and macOS, but Windows traditionally either hasn’t supported them (prior to Windows Vista) or has strictly limited their use. As a result, many cross-platform development tools, like Git for Windows, either didn’t support or didn’t enable symlink support on Windows.
All of this makes cross-platform development on Windows trickier. Fortunately, symlink support on current Windows is mature and functional. You do, however, have to jump through several extra hoops to make it work.
Make sure you’re running Windows 10 Creators Update or above. This is the first version to give the option of allowing users to create symlinks without needing UAC elevation. (Prior to that, any processes that needed to manipulate symlinks needed to be run as administrator; this extra step is both annoying and hurts security.)
Enable developer mode: Go under Settings, under Update & Security, under For developers, and set “Use developer features” to “Developer mode.” This is how you enable the Windows 10 Creators Update option of allowing users to create symlinks without UAC elevation.
As described in the Git for Windows documentation, you’ll also need to edit Windows’ local security policy to grant permissions to create symlinks. My personal preference is to use gpedit.msc, since that’s a standard Windows tool. It’s not installed with Home editions of Windows, but, as explained on AskVG, you can install it yourself using these commands.
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >Files.txt dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>Files.txt for /f %i in ('findstr /i . Files.txt 2^>nul') do dism /online /norestart /add-package:"C:\Windows\servicing\Packages\%i" del Files.txt
Incidentally, in case you’re wondering why all of this is necessary, the concern was that symlinks could be a security risk:
Symbolic links (symlinks) can expose security vulnerabilities in applications that aren’t designed to handle symbolic links. - Microsoft TechNet
Although more than a little hand-wavy, this argument is not without merit. Even on Unix-like operating systems, which have had decades to get used to symlinks, the occasional symlink race vulnerability pops up, and Windows software had been developed with no experience or expectation of this feature.
Configuring MinGW, Cygwin, and Git
Now you need to configure your software to make use of Windows’ new features.
For MSYS / MinGW (this includes the command-line utilities that used in the
git-bash shell), add an environment variable,
MSYS, and make sure it contains
winsymlinks:nativestrict. (If you don’t do this, then symlinks are
“emulated” by copying files and directories. This can be surprising, to say
For Cygwin, add an environment variable,
CYGWIN, and make sure it contains
winsymlinks:nativestrict. See the Cygwin
details. (If you don’t do this, then Cygwin defaults to emulating symlinks by
using special file contents that it understands but non-Cygwin software
For Git for Windows, make sure that the
core.symlinks config option is true.
In a normal Git system, this would be done at the system level (
--system core.symlinks true). However, Git for Windows adds an additional
“super-system” configuration file,
c:\\ProgramData\\Git\\config; this was
where I had to update
core.symlinks on my system. (This Stack Overflow
For Subversion, you’re out of luck. Even though Windows supports symlinks, the Subversion libraries don’t have the necessary code to take advantage of this.
Is there any other relevant software that needs configuration to support Windows symlinks? Let me know on Twitter.
Update: If you’re looking for a Windows GUI to help you manage all of these symlinks, the Link Shell Extension is very useful. It allows you to create symlinks, junction points, and more by right-dragging items in Explorer.