Skip to content

Commit

Permalink
change readme
Browse files Browse the repository at this point in the history
  • Loading branch information
jswh committed Aug 13, 2018
1 parent 3a4c198 commit 5e522f3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 112 deletions.
109 changes: 19 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,96 +1,25 @@
# WSLGit
## WSLEXE
The WSL system make a convenience of development on Windows.But the integretion to IDEs and code editors is not convenient.

This project provides a small executable that forwards all arguments
to `git` running inside Bash on Windows/Windows Subsystem for Linux (WSL).
The project [wslgit](https://github.com/andy-5/wslgit) makes a dummy exe that trying to receive the arguments and translating all paths from windows type to unix type, and reform these arguments to the real command in 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.
This shows a way to use wsl application in windows enviroment for ides or code editors. But the project is made for git only. I make a bit change using the file stem name as the real command. And it works!

## Download
## Usage

The latest binary release can be found on the
[releases page](https://github.com/andy-5/wslgit/releases).
1. download the [wsl.exe](https://github.com/jswh/wslexe/releases/tag/v0.0.1)
2. rename it to the command you want to use, for example pyhon.exe
3. change your ide or editor config to point to the executable file

## Compatibility
* python.exe
- [x] vscode
- [x] powershell
* composer.exe
- [x] phpstorm
* php.exe
- [x] phpstorm

## Usage in VSCode

To use this inside VSCode, put the `wslgit.exe` executable somewhere on
your computer and set the appropriate path in your VSCode `settings.json`:

```
{
"git.path": "C:\\CHANGE\\TO\\PATH\\TO\\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.


## Usage from the command line

Just put the executable somewhere on your `PATH` and optionally rename it
to `git.exe`. 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.


## Remarks

Currently, the path translation and shell escaping is very limited,
just enough to make it work in VSCode.

Only absolute paths are translated, because it is hard to detect if an
argument is a relative path or just some other string.
Also, VSCode always uses forward slashes for relative paths, so no
translation is necessary.

Additionally, be careful with special characters interpreted by the shell.
Only spaces and newlines in arguments are currently handled.


## Advanced Usage

Per default, `wslgit` executes `git` inside the WSL environment through bash
started in interactive mode. This is to automatically support the common case
where `ssh-agent` or similar tools are setup by `.bashrc` in interactive mode.
However, this may significantly slow down the execution of git commands.
To improve startup time, you can configure `wslgit` to execute git via a
non-interactive bash session. This can be achieved using one of the following
two methods:

- In Windows, set the environment variable `WSLGIT_USE_INTERACTIVE_SHELL` to
`false` or `0`. This forces `wslgit` to start bash in non-interactive mode.
- Alternatively, if 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.


## Building from source

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/`.

## Screen shot
#### python.exe for vscode
![show](https://user-images.githubusercontent.com/6405755/41839420-caa53562-7895-11e8-8ff8-576c56d9ba7c.gif)
44 changes: 22 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn shell_escape(arg: String) -> String {

fn use_interactive_shell() -> bool {
// check for explicit environment variable setting
if let Ok(interactive_flag) = env::var("WSLGIT_USE_INTERACTIVE_SHELL") {
if let Ok(interactive_flag) = env::var("WSL_USE_INTERACTIVE_SHELL") {
if interactive_flag == "false" || interactive_flag == "0" {
return false;
}
Expand All @@ -73,30 +73,30 @@ fn use_interactive_shell() -> bool {

fn main() {
let mut cmd_args = Vec::new();
let mut git_args: Vec<String> = vec![];
let git_cmd: String;
let mut wsl_args: Vec<String> = vec![];
let wsl_cmd: String;
let exe: String = env::args().next().unwrap();
let path = Path::new(&exe);
let file_stem = path.file_stem().unwrap().to_str().unwrap();
git_args.push(String::from(file_stem));
wsl_args.push(String::from(file_stem));

// process git command arguments
git_args.extend(env::args().skip(1)
// process wsl command arguments
wsl_args.extend(env::args().skip(1)
.map(translate_path_to_unix)
.map(shell_escape));
git_cmd = git_args.join(" ");
wsl_cmd = wsl_args.join(" ");

if use_interactive_shell() {
cmd_args.push("bash".to_string());
cmd_args.push("-ic".to_string());
cmd_args.push(git_cmd.clone());
cmd_args.push(wsl_cmd.clone());
}
else {
cmd_args.clone_from(&git_args);
cmd_args.clone_from(&wsl_args);
}

// setup stdin/stdout
let stdin_mode = if git_cmd.ends_with("--version") {
let stdin_mode = if wsl_cmd.ends_with("--version") {
// For some reason, the git subprocess seems to hang, waiting for
// input, when VS Code 1.17.2 tries to detect if `git --version` works
// on Windows 10 1709 (specifically, in `findSpecificGit` in the
Expand All @@ -110,43 +110,43 @@ fn main() {
Stdio::inherit()
};

// setup the git subprocess launched inside WSL
let mut git_proc_setup = Command::new("wsl");
git_proc_setup.args(&cmd_args)
// setup the wsl subprocess launched inside WSL
let mut wsl_proc_setup = Command::new("wsl");
wsl_proc_setup.args(&cmd_args)
.stdin(stdin_mode);
let status;

// add git commands that must use translate_path_to_win
const TRANSLATED_CMDS: &[&str] = &["rev-parse", "remote"];

let have_args = git_args.len() > 1;
let have_args = wsl_args.len() > 1;
let translate_output = if have_args {
TRANSLATED_CMDS.iter().position(|&r| r == git_args[1]).is_some()
TRANSLATED_CMDS.iter().position(|&r| r == wsl_args[1]).is_some()
} else {
false
};

if translate_output {
// run the subprocess and capture its output
let git_proc = git_proc_setup.stdout(Stdio::piped())
let wsl_proc = wsl_proc_setup.stdout(Stdio::piped())
.spawn()
.expect(&format!("Failed to execute command '{}'", &git_cmd));
let output = git_proc
.expect(&format!("Failed to execute command '{}'", &wsl_cmd));
let output = wsl_proc
.wait_with_output()
.expect(&format!("Failed to wait for git call '{}'", &git_cmd));
.expect(&format!("Failed to wait for wsl call '{}'", &wsl_cmd));
status = output.status;
let output_bytes = output.stdout;
let mut stdout = io::stdout();
stdout
.write_all(&translate_path_to_win(&output_bytes))
.expect("Failed to write git output");
.expect("Failed to write wsl output");
stdout.flush().expect("Failed to flush output");
}
else {
// run the subprocess without capturing its output
// the output of the subprocess is passed through unchanged
status = git_proc_setup.status()
.expect(&format!("Failed to execute command '{}'", &git_cmd));
status = wsl_proc_setup.status()
.expect(&format!("Failed to execute command '{}'", &wsl_cmd));
}

// forward any exit code
Expand Down

0 comments on commit 5e522f3

Please sign in to comment.