Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use wslpath for Insider Builds 17063 and later #12

Closed
Plailect opened this issue Dec 21, 2017 · 19 comments
Closed

Use wslpath for Insider Builds 17063 and later #12

Plailect opened this issue Dec 21, 2017 · 19 comments

Comments

@Plailect
Copy link

Windows Insider builds 17063 and later include a wslpath tool to translate between Linux and Windows style paths. This could be used in place of the current translate_path_to_unix and translate_path_to_win implementations. The options are as follows:

-a    force result to absolute path format
-u    translate from a Windows path to a WSL path (default)
-w    translate from a WSL path to a Windows path
-m    translate from a WSL path to a Windows path, with ‘/’ instead of ‘\\’

Source: https://blogs.windows.com/windowsexperience/2017/12/19/announcing-windows-10-insider-preview-build-17063-pc/

@andy-5
Copy link
Owner

andy-5 commented Dec 22, 2017

That looks great. I haven't access to a Insiders Build ATM, but I will eventually evaluate this approach to replace my functions.

@diablodale
Copy link
Contributor

If raw buffers were used instead of any coercion to UTF-8
...and to keep similar path-detection logic as today
code would need to check for a path on buffer[0] and one index after any LF found in buffer[] until the end. This requires line breaks to be only LF or CRLF.

The .lines() method WSLgit uses today to split lines is very concise and clean. On raw buffers like &[u8] there is no equivalent method. My instinct tells me there isn't a measurable perf or memory benefit to write new buffer splitting code. Here https://stackoverflow.com/questions/35901547/how-can-i-find-a-subsequence-in-a-u8-slice writes of some alternatives. Personally, I would lean towards a RegEx that can search for the LF and path as a unit. Then translate the path using an update to the current function -or-
outsource the path translation to wslpath.

A major roadblock for wslpath is that it only exists within WSL. There is no equivalent in Win32. The thought of repeatedly running wslpath from WSLgit makes me uncomfortable. As does splitting WSLgit
into two programs; one for each side of the Win32/WSL bridge. 😬

@andy-5
Copy link
Owner

andy-5 commented Mar 6, 2018

Yes, I'm also worried about these issues, but wslpath would enable things like honoring the new wsl.conf file, where users can e.g. specify a different mount point instead of /mnt, this would currently break wslgit. I would rather not duplicate the logic of handling these settings in wslgit.

@Plailect
Copy link
Author

Plailect commented May 1, 2018

This should no longer be limited just insider builds now that 1803 ("Spring Creators Update") has dropped.

@Stanzilla
Copy link

You would still need a version check since not everyone will upgrade nor even be offered the upgrade immediately.

@pd93
Copy link

pd93 commented Jul 24, 2018

@andy-5 I'd really appreciate the wslpath support. I currently use a custom mount point in the wsl.conf file in order to get docker volumes working via the WSL. Unfortunately, as you stated above, this breaks wslgit.

To address one of @diablodale 's concerns. You can now directly invoke wslpath without starting a login shell using the -e or --exec flag.

eg. wsl.exe -e wslpath <flags/args> will print the result nice and quickly instead of running all the user's runcom files like a login shell would.

@andy-5
Copy link
Owner

andy-5 commented Jul 26, 2018

While I'd also like to support wsl.conf, integrating wslpath is not entirely straight forward.

Translating Windows paths in arguments to wslgit to their WSL representation might work fine with wslpath, even if it probably slows down wslgit a bit (spawning a separate process that calls into WSL for each path argument might be costly, even without starting a login shell).

The more difficult part is identifying paths in the output of git that can be translated back to a corresponding Windows path. Currently, this is done by just looking for /mnt/DRIVE/PATH strings in the output. This isn't so easy if arbitrary mount points are allowed.

Maybe you can share your wsl.conf settings to provide an example use case?

@pd93
Copy link

pd93 commented Jul 26, 2018

I guess it could potentially make it slower again, but you could always query for the mount point prior to searching for output paths. eg. wsl.exe -e cat /etc/wsl.conf | grep root. Probably easier to parse the .ini in Rust though. I have not checked if "root" conflicts with any other keys.

My wsl.conf contains exactly this:

# Mount Windows drives to '/' instead of '/mnt/'
[automount]
root = /

As I stated previously, this config allows Docker volumes to mount in the proper way when using Docker via the WSL, so I imagine that I'm not the only one with a custom mount point. See this issue for details.

@hangxingliu
Copy link

I think the command bash.exe -c 'mount -t drvfs' maybe better then bash.exe -c 'grep /etc/wsl.conf -e root'. Because you can convert path more precise. For example:

The result of bash.exe -c 'mount -t drvfs' are:

C: on /c type drvfs (rw,noatime,uid=1000,gid=1000,umask=22,fmask=11,metadata)
D: on /where/mount/manually/d type drvfs (rw,noatime,uid=1000,gid=1000,umask=22,fmask=11,metadata)

Then, you can match path in the output by strings: /c and /where/mount/manually/d. And replace them to C: and D:.

(Because WSL allow you mount other drive manually same with other Linux platform by command mount. So for example: you can mount your USB drive to WSL by command: mount -t drvfs D: /mnt/myusb/)

@andy-5
Copy link
Owner

andy-5 commented Jul 30, 2018

Thanks @hangxingliu, that is an interesting idea.

Does anyone know if wslpath handles manually mounted paths also? Or does it only translate the automounted drives?

@pd93
Copy link

pd93 commented Jul 30, 2018

@andy-5 Just tried manually mounting a USB drive. Results below...

# Setup
sudo mkdir /e
sudo mount -t drvfs E: /e

wslpath E:\\
# Output: wslpath: E:\: No such file or directory

wslpath -w /e
# Output: E:\

Tried a few different things, but I can't get it to convert from a Windows path to a WSL one. The other way around works fine. I've tried starting a new shell and a few different paths on my USB. No luck.

I don't have a second hard drive in my laptop, but I can test that tonight on my desktop.

@nickjj
Copy link

nickjj commented Dec 16, 2018

Any progress on this?

Using Windows 18.09 (stable release) and a mount point of /, I get this output without modifying wslpath:

nick@workstation:/e/src/tmp$ wslpath E:\\
/e/

nick@workstation:/e/src/tmp$ wslpath -w /e
E:\

My /etc/wsl.conf looks like this:

nick@workstation:/e/src/tmp$ cat /etc/wsl.conf
[automount]
root = /
options = "metadata"

And mount -t drvfs looks like this:

nick@workstation:/e/src/tmp$ mount -t drvfs
C: on /c type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
D: on /d type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
E: on /e type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
F: on /f type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
G: on /g type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)

@andreialecu
Copy link

For anyone else landing on this issue like I did, there is now a wslgit-mount-at-root.exe that uses / instead of /mnt on the releases page at https://github.com/andy-5/wslgit/releases

Should be a decent workaround for most of the reasons this was requested.

@carlolars
Copy link
Contributor

In lack of a better way why not just make an env-var in windows that if set its value is used as the mount root, for example WSLGIT_MOUNT_ROOT = / would use '/' as mount root.
If the user can find out how to change the mount root in wsl they will probably also be able to figure this out =)

@andy-5
Copy link
Owner

andy-5 commented Jun 17, 2019

@carlolars That's a good idea, this should cover the most common use cases. Although it introduces a little bit of duplication with wsl.conf.

@carlolars carlolars mentioned this issue Jul 4, 2019
@carlolars
Copy link
Contributor

I've implemented support for custom mount root using WSLGIT_MOUNT_ROOT environment variable.

First I tried with detecting the mount root by finding the mount point for a windows drive from the output of mount -lt drvfs but that required invoking a process that doubled the execution time.
I also considered reading the mount root directly from the wsl.conf file via the windows file system, it would require first finding out which distribution is the default (used by wsl.exe) to know where to look for wsl.conf, and afaik that is done by calling wslconfig.exe/wsl.exe depending on windows version => invoking process...

@carlolars
Copy link
Contributor

Maybe wslpath could be used with something like this:

$ PATH1=$(wslpath C:\\Users\\carl-oskar\\workspace\\wslgit\\README.md) && git diff $PATH1

@andy-5
Copy link
Owner

andy-5 commented Oct 1, 2019

@carlolars That is an interesting idea, at least for the win->linux conversation. The output of the git command still needs to be processed separately.

@andy-5
Copy link
Owner

andy-5 commented Jan 10, 2020

I've just released v0.9.0, which now uses wslpath to translate all paths. Thanks @carlolars for implementing this.

@andy-5 andy-5 closed this as completed Jan 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants