Search code examples
linuxwindowsgitvisual-studio

git status between Windows and Linux does not agree


Git status returns different results if I run it on my Linux system and my Windows10 laptop.

The original directory was started on the Linux machine (running RedHat 6.4). I got tired of editing all of our Python code using VIM, so I decided to map a network drive on my Windows10 laptop to the remote Linux box (which controls all of our test equipment) and the directory set up with Git. So now I can use Visual Studio Code to easily view/edit/update any files on the remote Linux machine. I run all my git commands from the Linux box, but it would be nice if I could run them right from VS Code, but there is obviously a difference between the two versions of Git.

'git status' --> on the Linux box returns no updated or modified files.

'git status' --> on Windows shows I have over 200 modified files and 2 directories that are deleted.

I have already looked through this thread: Git - Windows AND linux line-endings

There was a lot of great information there that I have tried. The only thing that seemed to have any effect at all though was adding the 'git config core.filemode false' setting, which I did on the Linux machine. Now, when I run 'git status' on my Windows machine I see it reduced my modified files from 200+ down to 4. So that is great. However, and I still see those 4 files as modified and the 2 folders it thinks are deleted.

Any other suggestions as to what I can check?

As a side note, I have 112 files that show up as Untracked in VS Code, but not coincidentally I believe, all 112 are files that reside in the 2 directories that Windows git status think are deleted.


Solution

  • Git stores, in the index, some special bits of information to know easily whether a file in the work-tree is modified or not. The index itself is a file that resides within the Git repository (.git/index; there may be additional auxiliary files, and temporary index files, here, but .git/index is the index, the first and real-est, as it were).

    These special bits of information in the index are (derived from) the result of operating system stat calls. The stat calls on Linux and the stat calls on Windows deliver different data (specifically st_dev, though the ino, uid, and gid can also be an issue), so a single index (and hence Git repository-and-work-tree) cannot1 be correctly shared across a machine boundary. This holds for network drives, VM images, Dropbox folders (which have other issues), or any other sharing mechanism that allows either system to directly view the other system's data.

    The end result of all of this is that it's sometimes, just barely, possible to share a Git repository this way, but it's a bad idea: you'll get odd effects, such as Git missing some modified files, or thinking files are modified when they aren't. The latter is what you're seeing, probably.

    It really works a lot better, though, not to share repository directories (nor work-trees) like this. That's even true on "friendlier" systems, such as MacOS vs Linux when using VMs and, e.g., vagrant. It sort of works, sometimes, but it just is not reliable. Use separate clones and your life will be happier.


    1At compile time, one can choose to have Git ignore the st_dev field, to enable sharing across network drives. That sometimes makes a difference, and sometimes doesn't. I suspect this option is chosen in most Windows builds so that Windows can share with Windows, but is not enabled in Linux builds, which means the Linux side won't ignore changes made by the Windows side—which will result in odd behavior.

    The timestamps are normally compatible, but if one enables nanosecond-resolution time stamps, that may also be problematic.