windowsgitwindows-subsystem-for-linuxgit-for-windowsgit-init

Git shows all files changed when "git init" was used in WSL and "git diff" in Windows


If I use git init in WSL, then continue with git operations in Windows, git for Windows will show that most or all files have changed, even if they haven't.

Notably, the inverse produces no issue. Using git init in git for Windows, then continuing in WSL, works just as expected.

Example/repro

#!/bin/bash OR cmd.exe
mkdir test
cd test 
git init 
echo "hello" > test.txt
git add test.txt
git commit -m "test commit"
code .

If this code is run entirely in CMD, there's no problem. VSCode (or any other editor - I've also tried with Visual Studio, PyCharm, and neovim) will accurately show that there are no changes to test.txt. The same is true of running it entirely in WSL. All editors accurately show that there is no change to the file.

However, if I run git init in WSL, then continue working in Windows (such as opening a code editor in Windows), it will show that most or all files have been changed, even if they have not been.

What I've tried

  1. I've considered that this could be an issue with CRLF/LF, but configuring .gitattributes and/or configuring my editor to leave line endings as they are found seems to have been no help.
  2. I've tried changing the OS's run. I've found that I can reproduce the issue across all versions of Windows I've tried, but have been unable to reproduce it on other versions of WSL (having tried Ubuntu of wsl --install Ubuntu).

Extra Info


Solution

  • You don't mention it, but I'm assuming the files you are referring to are on the Windows drive, not the WSL filesystem

    What you are seeing is likely because, by default, WSL assigns 777 (-rwxrwxrwx) permissions to all files it creates on the Windows filesystem. This isn't a security risk as WSL runs under your Windows user permissions, so there's no elevation possible. A file with "fully open" Linux permissions is still going to be restricted by Windows permissions.

    As far as I can tell, this "loose permission" assignment is primarily for performance reasons.

    But it means that the files appear with with different permissions in Git under WSL vs. Git under Windows. This is why Git on Windows believes the file has changed -- The permissions are different, and by default, Git stores permissions as part of the commit.

    If this is what is causing your issue, then there are several possible solutions:

    Recommended - Keep files in WSL/Linux filesystem

    If possible, keep your development files on the Linux filesystem. You'll notice that VSCode recommends this when you edit files through WSL on the Windows filesystem. The main reason for this is performance.

    Alternative - Set Metadata for WSL-created files

    But if you really do need your project on the Windows filesystem, the good news is that you can configure your WSL distribution to add "metadata" to each file that will allow it to "pretend" that each file on the Windows filesystem really does have Linux permissions.

    To do this, create or edit /etc/wsl.conf inside your WSL distribution, and add the following:

    [automount]
    options = "metadata,umask=22,fmask=11"
    

    Then exit the WSL distribution, wsl --shutdown (or --terminate) and restart.

    You should find that files created on the Windows filesystem now have 644 (-rw-r--r--) permissions, and they'll appear the same on the Windows side. As a result, I'm hoping that you won't get these mismatches any longer.

    See also (educational, but not recommended)

    How do I make Git ignore file mode (chmod) changes?