Dangers of setting SSH path in Git config
Using SSH with Git on Windows mostly works out of the box. The .gitignore
file allows a lot of additional configuration. The sshCommand
in the core
section allows you to specify the path and arguments for the ssh.exe
command. However, specifying a path there is mostly asking for trouble.
The ssh.exe
command is located in C:\Windows\System32\OpenSSH
on Windows. So the correct setting in .gitignore
should be:
[core]
sshCommand = \"C:\\Windows\\System32\\OpenSSH\\ssh.exe\"
If you try to use Git with SSH from the command line after setting this, it will actually work as expected. However, if you try to use it from Visual Studio, it fails with the following error message:
"C:\Windows\System32\OpenSSH\ssh.exe": C:\Windows\System32\OpenSSH\ssh.exe: No such file or directory
The reason for this is the Windows file system redirector which redirects some of the system paths for 32-bit processes, as stated in the documentation:
In most cases, whenever a 32-bit application attempts to access
%windir%\System32
,%windir%\lastgood\system32
, or%windir%\regedit.exe
, the access is redirected to an architecture-specific path.
So, for a 32-bit process, the above path is actually C:\Windows\SysWOW64\OpenSSH\ssh.exe
. This file does not exist, hence the error.
It is also interesting to note that the error occurs in both Visual Studio 2019 (which is 32-bit) and Visual Studio 2022 (which is 64-bit). This is the case because both call Git from a separate 32-bit process.
There is a way for a 32-bit process to access C:\Windows\System32\OpenSSH\ssh.exe
, as stated in the documentation:
32-bit applications can access the native system directory by substituting
%windir%\Sysnative
for%windir%\System32
. WOW64 recognizesSysnative
as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use theSysnative
alias as it is a virtual directory not a real one.
This means that the correct path in .gitignore
for 32-bit applications would be as follows:
[core]
sshCommand = \"C:\\Windows\\SysNative\\OpenSSH\\ssh.exe\"
With this setting Visual Studio works fine. But now Git does not work from the command line because the Sysnative
alias does not work for 64-bit applications, as explained in the quote above:
"C:\Windows\SysNative\OpenSSH\ssh.exe": C:\Windows\SysNative\OpenSSH\ssh.exe: No such file or directory
There is simply no path that could be used for a file in a system folder like C:\Windows\System32
that would work for both 32-bit and 64-bit applications. This means that you should not specify such a path in a configuration file that is read by both 32-bit and 64-bit processes.
So what is the recommendation for the sshCommand
setting in .gitignore
? Do not use it to set a path to the command. The folder containing ssh.exe
(and related commands) should be in the path by default, so you can invoke the command from anywhere without having to specify the path. If it is not, simply add C:\Windows\System32\OpenSSH
to the path.