Skip to content

Instantly share code, notes, and snippets.

@onecrayon
Last active April 21, 2024 22:18
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onecrayon/de756538d5331f7592065507c03b1864 to your computer and use it in GitHub Desktop.
Save onecrayon/de756538d5331f7592065507c03b1864 to your computer and use it in GitHub Desktop.
Use git installed in Windows Subsystem for Linux in Visual Studio Code

Proxy commands from Windows command line to Bash using the Windows Subsystem for Linux (WSL)

These scripts allow you to proxy commands (specifically git, in this example) to the Windows Subsystem for Linux from the normal Windows command line environment. This allows you to work with a single installation of git (under your Linux distribution) instead of trying to manage two concurrent installations.

I explicitly created these scripts to allow using Git in Visual Studio Code without installing it under Windows.

Please note that I have not extensively tested edge cases! If you run into problems, please let me know!

Using WSL git in Visual Studio Code

  1. Install the scripts somewhere on your normal Windows drive; e.g. C:\Users\USERNAME\dev\proxy_scripts.
  2. In VSC, modify your settings.json file and add the git.path setting pointing to your git.bat file; e.g. "git.path": "c:\\Users\\USERNAME\\dev\\proxy_scripts\\git.bat"
  3. Enjoy WSL git from the VSC GUI! (You might need to relaunch the app.)

Proxying further commands

If you want to proxy further commands, you can do so by duplicating git.bat and changing the command that is getting invoked (so replace git on line 6 with whatever command you want to proxy). Presumably, you could also add these scripts to your Windows PATH if you wanted to go the extra mile, though I'm not sure how that would interact with the WSL bash.exe environment (could end up round-tripping everything uselessly, if your Windows binary locations occur earlier in the PATH than the WSL ones).

Please enjoy responsibly!

Prior art

@echo off
:: Properly escape the command
:: Many thanks to wsl-alias for this logic: https://github.com/leongrdic/wsl-alias
set cmd=%*
set cmd=%cmd:\"=\\"%
set cmd=%cmd:\'=\\'%
set cmd=%cmd:\=/%
set cmd=%cmd://=\\%
set cmd=%cmd:"=\"%
set cmd=%cmd:'=\'%
set cmd=%cmd:(=\(%
set cmd=%cmd:)=\)%
:: Grab the path to our proxy Bash script (%~dp0 is the directory of this batch file)
set bash_proxy=%~dp0_proxy_cmd.sh
set bash_proxy=%bash_proxy:\=\\%
:: Pass things off to the Bash script
bash.exe -c "$(wslpath %bash_proxy%) %cmd%"
##
# Evaluates command, parsing paths at both ends (Windows => Unix => Windows)
#
# Benefits to doing this instead of directly invoking the command in the batch file:
#
# + Easier to convert path arguments to Unix paths
# + sed regex does not require double escaping backslashes (not embedded in double quotes)
##
cmd=()
for arg in "$@"
do
if [[ $arg =~ ^[a-zA-Z]:/ ]]; then
cmd+=( $(wslpath "$arg") )
else
cmd+=("$arg")
fi
done
# TODO: Look into ways to convert inline paths via `wslpath` instead of hard-coding `/mnt` search
# Kind of a tricky issue, because our output could be basically anything
eval "${cmd[@]}" | sed \
-e 's|"/mnt/\([a-zA-Z]\)/\([^"]*\)"|"\1:/\2"|g' \
-e "s|'/mnt/\\([a-zA-Z]\\)/\\([^']*\\)'|'\\1:/\\2'|g" \
-e 's|/mnt/\([A-Za-z]\)/\([^ ]*\)|\1:/\2|g' \
-e 's|/|\\|g'
@echo off
:: %~dp0 is the directory of this batch file
set proxy_path=%~dp0_proxy_cmd.bat
:: %* is the full command passed to this batch file
%proxy_path% git %*
@alerGeek
Copy link

Hey,
Thanks for sharing script - it is really nice and seems to be working for VSC!

I have tried to use Git this way not only for VSC, but globally for Windows.
I have added proxy_script directory to PATH environment and command git is recognizable across multiple shells: ie. powershell.

However, I have the problem with making commands which chars like ' and "
For example: git commit

PS D:\repos\some-repo> git commit -m "init version, lab1, lab2, lab4"

results in error like:

PS D:\repos\some-repo\studia\6semestr\inzynieria-systemow-mobilnych> git commit -m "init version, lab1, lab2, lab4"
error: pathspec 'version,' did not match any file(s) known to git
error: pathspec 'lab1,' did not match any file(s) known to git
error: pathspec 'lab2,' did not match any file(s) known to git
error: pathspec 'lab4' did not match any file(s) known to git

Error may be solved by commenting

:: set cmd=%cmd:\"=\\"%
:: set cmd=%cmd:\'=\\'%

in _proxy_cmd.bat, however I am not sure if this will not break something else.

Is there a reason why these characters have been added to the mapping as well?

@onecrayon
Copy link
Author

@alerGeek I pulled the quotation commenting directly from the wsl-alias project: https://github.com/leongrdic/wsl-alias I am not sure what prompted it to be included there, but at a guess you will run into trouble with commands in which you have escaped quotation marks if you leave that commented out. I imagine if you avoid trying to escape quotation marks prior to passing them through the proxy, you will be unlikely to run into trouble, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment