Skip to content

Support for WSL git using wslgit #305

Closed

Description

@carlolars

I've been experimenting with using git from WSL by simply just replacing Forks git.exe with a modified wslgit.exe, and it almost works :)

The only thing I've found so far that does not work is interactive rebase.
The reason is likely because the path to the git-rebase-todo file that is passed to Fork.RI.exe is a unix path, for example /c/Users/carl-oskar/workspace/example/.git/rebase-merge/git-rebase-todo, which is not handled correctly throwing a DirectoryNotFoundException for the path 'C:\c\Users\carl-oskar\workspace\wslgit\.git\rebase-merge\git-rebase-todo' (I think the 'C:' prefix is added automatically for paths that begin with \). See this fork.log gist for the error.

If you would like to investigate I have pushed the changes to carlolars/wslgit for-fork branch, if you don't want to build yourself I have added a binary to release: beta-for-fork

Activity

  1. DanPristupov commented on Jun 8, 2019

    @DanPristupov
    Contributor

    It looks like .Net can't handle paths like /c/Users/.

    Same problem happens with my path File.ReadAllLines("/Z/Sources/repo/.git/rebase-merge/git-rebase-todo")

  2. carlolars commented on Jun 8, 2019

    @carlolars
    Author

    It apparently interprets paths starting with '\' (or '/') as "An absolute path from the root of the current drive.", which explains the 'C:' prefix (source).

    From here, "Almost all paths passed to Windows APIs are normalized" and "This normalization happens implicitly, but you can do it explicitly by calling the Path.GetFullPath method".

    The simple solution would be to support only the two most common WSL mount roots (/mnt/ and /) and just strip the mount root and drive letter from the start of paths.

    I wrote a small program for testing, can be found here

  3. carlolars commented on Jun 22, 2019

    @carlolars
    Author

    Hi again!

    I've been using Fork with wslgit for two weeks now without any problems, even interactive rebase works using the Fork GUI.

    I'm using an approach inspired by how VSCode is started from within WSL. When starting VSCode using code it runs a shell scrip that executes the actual code.exe binary, and depending on which environment the script is executed in it does different things.

    So I placed a script that I named Fork.RI in the Fork app-folder next to the real Fork.RI.exe, the script can be found in this gist. This script executes the Fork.RI.exe binary after translating the argument, which is the path to the git-rebase-todo file, to windows style.

    I then replaced Fork's git.exe with a custom version of wslgit.exe, this modified version replaces the string Fork.RI.exe with just Fork.RI in all arguments, so that these arguments to git rebase

    -c sequence.editor="C:/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI.exe"
    -c core.editor="C:/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI.exe"
    

    became

    -c sequence.editor="C:/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI"
    -c core.editor="C:/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI"
    

    which makes the git-rebase-interactive script call the Fork.RI script instead of Fork.RI.exe.
    I've only verified that the script works for WSL, but it should not be any problems using the same script with MSYS or cygwin.

    So my wish is that you

    1. Add some way to select a custom git binary, totally ok if it is not available from the GUI but only exists in settings.json.
    2. Instead of using Fork.RI.exe directly as editor for interactive rebase use a wrapper script like this one.
  4. carlolars commented on Aug 13, 2019

    @carlolars
    Author

    Hi,

    I just pushed a patch for wslgit to my fork at https://github.com/carlolars/wslgit/releases/tag/v0.8.0-pre-fork-patch.
    I've been using it at work and at home for two months now and it works for me.

  5. DanPristupov commented on Aug 13, 2019

    @DanPristupov
    Contributor

    I'm thinking of introducing FORK_GIT_PATH ENV variable to specify path to a custom git instance. Can it be helpful?

  6. carlolars commented on Aug 13, 2019

    @carlolars
    Author

    Yes that would help.
    But Fork.RI.exe would also have to be replaced with a script that handles the translation of Unix-paths to Windows-paths when needed (WSL) and then calls the actual Fork.RI.exe, see my script here, and that script would have to be passed as argument to sequence.editor and core.editor instead of the exe.

    Here is how it should work when using wslgit:

    1. Fork.exe [Win]:
      Calls git rebase with the Fork.RI script as editor
      git.exe rebase -i -c sequence.editor="C:/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI" ...
    2. git.exe (=wslgit.exe) [Win]:
      Converts paths from win to unix and then calls git inside WSL:
      wsl git rebase -i -c sequence.editor="/C/Users/user/AppData/Local/Fork/app-1.35.0/Fork.RI" ...
    3. git [WSL]:
      Creates the git-rebase-todo file and then calls the sequence.editor (Fork.RI script) with the path to the git-rebase-todo:
      .../Fork.RI /c/path/to/git-rebase-todo
    4. Fork.RI [WSL]:
      The script converts the git-rebase-todo path from unix to windows style and then calls Fork.RI.exe
      .../Fork.RI.exe c:/path/to/git-rebase-todo
    5. Fork.RI.exe [Win]:
      Opens the git-rebase-todo file for editing.
  7. Stanzilla commented on Jan 8, 2020

    @Stanzilla

    @carlolars been looking for something like this, did you ask @andy-5 if there is any chance we could have this in upstream or did that already happen and I missed it?

  8. carlolars commented on Jan 16, 2020

    @carlolars
    Author

    @carlolars been looking for something like this, did you ask @andy-5 if there is any chance we could have this in upstream or did that already happen and I missed it?

    No, I haven't asked him. It sure would be nice to have it in the upstream. I'll clean it up a little and make a PR and see if he will accept it.

    I'll need to do some changes so that the "fork-patch" is not active for everyone. Prefferably it should only be active when invoked from Fork, @DanPristupov is it safe to assume that the FORK_PROCESS_ID variable is set when git.exe is called from Fork? I've noticed it on all calls I've checked except the initial git version iirc, which is fine.

  9. DanPristupov commented on Mar 4, 2020

    @DanPristupov
    Contributor

    @carlolars ouch, I missed your questions. I'm sorry!

    I just checked the source code, FORK_PROCESS_ID is being set for every git request. Fork uses this ID to identify the parent Fork instance when user run multiple Fork processes.

  10. DanPristupov commented on Mar 4, 2020

    @DanPristupov
    Contributor

    OK, I tried to find out what's going on, but didn't succeed.

    Looks like all Windows paths (including the working directory) must be converted to /c/path/to format. May be I'll try later when I have more time.

    P.S. I didn't realize that you try to run a 3rd party project, not the official WSL distribution.

  11. Stanzilla commented on Mar 4, 2020

    @Stanzilla

    Well supporting WSL directly without the need for WSLGit would be preferred anyway, but I guess that would end up with you reimplementing a lot of that. For path conversion you can use wslpath.exe that comes with Windows

  12. carlolars commented on Mar 5, 2020

    @carlolars
    Author

    P.S. I didn't realize that you try to run a 3rd party project, not the official WSL distribution.

    Well, wslgit.exe is an application for Windows that can be used as git-client instead of Git for Windows. It acts as a proxy that translates the arguments from Windows style to Linux style and passes them to the git binary inside (official) WSL and then translates the output from WSL-git to Windows style and passes the output back to the calling Windows application. The Windows application thinks that it is using a git client for Windows.

    It actually works really well now when using wslgit as git client in Fork, with the exception that it is not possible to browse to the WSL-filesystem via the \\wsl$ path but that is for another issue.

    I'm closing this issue now as it has served its purpose and there is nothing more to do here, the fixes needed has been added to the official wslgit project and is just waiting to be released.

  13. Stanzilla commented on Mar 7, 2020

    @Stanzilla

    @carlolars do you think the wsl path issue should/needs to be fixes in Fork or in WSLGit?

  14. carlolars commented on Mar 8, 2020

    @carlolars
    Author

    @carlolars do you think the wsl path issue should/needs to be fixes in Fork or in WSLGit?

    It must be fixed in the Fork application since it is the browse folder dialog that needs changing.

  15. Ridder90 commented on Apr 7, 2020

    @Ridder90

    I am experimenting with Fork as a git GUI for repo's living in WSL. But unfortunately I am experiencing random freezes or delayed detection of changes. Besides configuring WSLgit as the shell in the Fork preferences, are there any other changes to be made to make this work?

    Are those Fork.RI edits for e.g. still needed?

    Would love to see this work!

  16. mloskot commented on Mar 27, 2021

    @mloskot

    It is possible to launch Fork from WSL:

    /mnt/c/Windows/System32/cmd.exe /c "%USERPROFILE%\AppData\Local\Fork\Fork.exe "$(wslpath -w -a .)"
    
  17. carlolars commented on Mar 27, 2021

    @carlolars
    Author

    @mloskot Nice! Got me thinking, so now I've added this to my .bashrc so I can launch Fork from WSL using just fork or fork some/path:

    # Full path to Fork.exe
    FORK_PATH=/c/Users/user.name/AppData/Local/Fork/Fork.exe
    # If Fork.exe exists then make it executable
    [ -e "$FORK_PATH" ] && chmod +x "$FORK_PATH"
    # If Fork.exe exists and is executable then add alias
    [ -x "$FORK_PATH" ] && alias fork='_fork_exe'
    _fork_exe() {
        # Launch Fork.exe using the first argument as path or in the current working
        # dir if no path was provided. The path must exist and be inside a git-repo.
        path=${1:-$PWD}
        (pushd "$path" && git rev-parse && popd) >/dev/null || return 1
        path=$(wslpath -aw "$path")
        $FORK_PATH "$path"
    }

    One problem I've found is that when I open a repository that is not already opened in Fork (has a tab) then a new instance of Fork is started.

  18. mloskot commented on Mar 27, 2021

    @mloskot

    @carlolars

    One problem I've found is that when I open a repository that is not already opened in Fork (has a tab) then a new instance of Fork is started.

    Yes, I noticed that too.

  19. mikemaccana commented on May 25, 2022

    @mikemaccana

    Pardon reopening a closed thread but I'm trying wslgit in Fork - picking C:\Program Files\wslgit\bin\git.exe seems to work but Fork doesn't show the new git instance in it's UI afterwards:

    image

    Does anyone know how to make wslgit default in Fork?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions