This project provides a small executable that forwards all arguments to git running inside Bash on Windows/Windows Subsystem for Linux (WSL).
The primary reason for this tool is to make the Git plugin in Visual Studio Code (VSCode) work with the git command installed in WSL. For these two to interoperate, this tool translates paths between the Windows (C:\Foo\Bar) and Linux (/mnt/c/Foo/Bar) representations.
The latest binary release can be downloaded from the releases page.
[Optional 1] Run the install.bat script as administrator.
The install.bat script creates a folder structure similar to the one used by Git For Windows, and creates some useful symbolic links in the wslgit\cmd and wslgit\bin folders.
[Optional 2] Add the wslgit\cmd directory to your Windows Path environment variable (user or system).
To change the environment variable, type Edit environment variables for your account into Start menu/Windows search and use that tool to edit Path.
You may also need to install the latest Microsoft Visual C++ Redistributable for Visual Studio 2017.
When accessing files on the filesystem in a WSL distribution using the UNC path (\\wsl$\dist\path or \\wsl.localhost\dist\path) then the distribution used is extracted from the path. This means that git must be setup correctly in all distributions that you intend to access.
When accessing files on the Windows filesystem or a mapped network drive the default WSL distribution is used unless the WSLGIT_DEFAULT_DIST environment variable is set.
If the default WSL distribution is of WSL2 type then it is highly recommended to set the WSLGIT_DEFAULT_DIST to the name of a WSL1 instance since WSL1 is both quicker at accessing the Windows filesystem and can access mapped network drives which WSL2 cannot.
Tip: use symlinks to map files and folders in all distributions to a common directory to avoid having to maintain multiple copies, for example you can link the
~/.sshfolder in all WSL dists to the.sshfolder in your Windows home folder.
VSCode will find the git executable automatically if the two optional installation steps were taken.
If not, set the appropriate path in your VSCode settings.json:
{ "git.path": "C:\\CHANGE\\TO\\PATH\\TO\\wslgit\\cmd\\wslgit.exe" } Also make sure that you use an SSH key without password to access your git repositories, or that your SSH key is added to a SSH agent running within WSL before starting VSCode. You cannot enter your passphrase in VSCode!
If you use a SSH agent, make sure that it does not print any text (like e.g. Agent pid 123) during startup of an interactive bash shell. If there is any additional output when your bash shell starts, the VSCode Git plugin cannot correctly parse the output.
If you did the two optional installation steps then you can then just run any git command from a Windows console by running wslgit COMMAND or git COMMAND and it uses the Git version installed in WSL.
To make Fork use git from WSL you must have done the first optional installation step (run install.bat). Then go to the Fork preferences and select a custom git instance where you point it to the git.exe in the wslgit\bin folder (not the cmd folder!).
If getting an error message about not being able to execute Fork.RI then make sure that the Fork.RI script is executable inside WSL (run chmod +x Fork.RI if needed).
Currently, the path translation and shell escaping is very limited, just enough to make it work in VSCode.
All absolute paths are translated, but relative paths are only translated if they point to existing files or directories. Otherwise it would be impossible to detect if an argument is a relative path or just some other string. VSCode always uses forward slashes for relative paths, so no translation is necessary in this case.
Additionally, be careful with special characters interpreted by the shell. Only spaces and newlines in arguments are currently handled.
To automatically support the common case where ssh-agent or similar tools are setup by .bashrc in interactive mode then, per default, wslgit executes git inside the WSL environment through bash started in interactive mode for some commands (clone, fetch, pull and push), and bash started in non-interactive mode for all other commands.
The behavior can be selected by setting an environment variable in Windows named WSLGIT_USE_INTERACTIVE_SHELL to one of the following values:
falseor0- Forcewslgitto always start in non-interactive mode.true,1, or empty value - Forcewslgitto always start in interactive mode.smart(default) - Interactive mode forclone,fetch,pull,push, non-interactive mode for all other commands. This is the default if the variable is not set.
Alternatively, if WSLGIT_USE_INTERACTIVE_SHELL is not set but the Windows environment variable BASH_ENV is set to a bash startup script and the environment variable WSLENV contains the string "BASH_ENV", then wslgit assumes that the forced startup script from BASH_ENV contains everything you need, and therefore also starts bash in non-interactive mode.
This feature is only available in Windows 10 builds 17063 and later.
Set a Windows environment variable called WSLGIT_DEFAULT_DIST to the name of a WSL distribution to use instead of the WSL default distribution when accessing files on the Windows filesystem or from mapped network shares.
Note, to access files on a mapped network drive a WSL1 distribution must be used.
wslgit set a variable called WSLGIT to 1 and shares it to WSL. This variable can be used in .bashrc to determine if WSL was invoked by wslgit, and for example if set then just do the absolute minimum of initialization needed for git to function.
Combined with WSLGIT_USE_INTERACTIVE_SHELL=smart (default) this can make every git command execute with as little overhead as possible.
This feature is only available in Windows 10 builds 17063 and later.
First, install Rust from https://www.rust-lang.org. Rust on Windows also requires Visual Studio or the Visual C++ Build Tools for linking.
The final executable can then be build by running
cargo build --release inside the root directory of this project. The resulting binary will be located in ./target/release/.
Tests must be run using one test thread because of race conditions when changing environment variables:
# Run all tests cargo test -- --test-threads=1 # Run only unit tests cargo test test -- --test-threads=1 # Run only integration tests cargo test integration -- --test-threads=1 # Run benchmarks (requires nightly toolchain!) cargo +nightly bench