Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing git repo symlinks between Windows and WSL

I have the following setup:

  • WSL installed with Ubuntu, with git already installed there
  • git installed from https://git-scm.com on the Windows side
  • Symlink creation enabled by turning on Developer Mode and adding my user to the correct policy group, as explained at https://github.com/git-for-windows/git/wiki/Symbolic-Links
  • core.symlinks=true (due to above line)
  • core.autocrlf=false (I don't want git to do any cleverness, I'm sharing the repo between Windows and WSL)

This almost works perfectly (very impressed). When I clone a repository, it is all okay in both Windows and WSL, apart from the symlinks on one of the two sides say they are modified but they are not. On both sides the symlinks work correctly, I can navigate them without issue.

After an initial clone (on the Windows side), Windows PowerShell gives:

PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

However on the WSL side, it says that the two symlinks are modified:

/mnt/c/Users/Matthew/Projects/...$ git status 
On branch master 
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory) 

        modified:   t/browser 
        modified:   web/jslib

no changes added to commit

But git diff gives no output:

/mnt/c/Users/Matthew/Projects/...$ git diff
/mnt/c/Users/Matthew/Projects/...$ 

If I then reset the checkout on the WSL side, it all switches round:

/mnt/c/Users/Matthew/Projects/...$ git reset --hard HEAD 
HEAD is now at ......... Commit message here
/mnt/c/Users/Matthew/Projects/...$ git status 
On branch master 
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

And back on Windows Powershell:

PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   t/browser
        modified:   web/jslib

no changes added to commit (use "git add" and/or "git commit -a")
PS C:\Users\Matthew\Projects\...> git diff
PS C:\Users\Matthew\Projects\...> 

It seems like git is setting an internal flag that it then considers changed in the other system; is there any way to fix or work around this?

like image 536
M Somerville Avatar asked Jun 08 '19 08:06

M Somerville


People also ask

Does Git support symlinks on Windows?

Although Git supports symlinks, I would strongly recommend against storing them as links in your repository, especially if you're also working with that code on Windows.

Can you use git in WSL?

Git can be installed on Windows AND on WSL The root of your file system / is the mount point of your root partition, or folder, in the case of WSL.

Does Git work with symlinks?

Git can track symlinks as well as any other text files. After all, as the documentation says, a symbolic link is nothing but a file with special mode containing the path to the referenced file.

How do I access Windows directory from WSL?

Accessing your Windows files in the WSL terminal Just use the cd command to navigate to your WSL root folder, then navigate into the mnt folder to access your C: drive.


2 Answers

Found a workaround. I created alias in wsl to Git for windows: alias git="/mnt/c/Program\ Files/Git/bin/git.exe". Works perfect!

like image 66
Dima Kalinin Avatar answered Oct 02 '22 04:10

Dima Kalinin


This issue occurs because Windows and Linux (or at least the emulated version) disagree about the size of a symlink. On Windows, a symlink's size is in blocks, so a 6-character symlink will be 4096 bytes in size. On Linux, a symlink's size is the number of bytes it contains (in this example, 6).

One of the things that Git writes into the index to keep track of whether a file has changed is the size. When you perform any sort of update of the index, such as with git reset --hard, Git writes all of this metadata into the index, including the size. When you run git status, git checks this metadata to determine if it matches, and if not, it marks the file as modified.

It is possible to control whether certain information is checked in the index, since some tools can produce bogus info (for example, JGit doesn't write device and inode numbers), but size is always checked, because it is seen as a good indicator of whether a file has changed.

Since this is a fundamental disagreement between how Windows and how WSL see the symlink, this really can't be fixed. You could try asking the Git for Windows project if they'd be willing to work around this issue in Git for Windows, but I suspect the answer is probably going to be no since changing it would likely have a performance impact for all Windows users.

like image 37
bk2204 Avatar answered Oct 02 '22 05:10

bk2204