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.
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%\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%\System32. WOW64 recognizes
Sysnativeas 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 the
Sysnativealias 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.