How to make GIT treat directory junctions as regular folders on Windows?
Asked Answered
C

1

6

I need share to share certain files between different projects. Thus I have a file structure like so:

D:\shared\
D:\shared\files-shared-by-all-projects-here

D:\project1\
D:\project1\project1-specific-files-here
D:\project1\shared <- directory junction to D:\shared

D:\project2\
D:\project2\project2-specific-files-here
D:\project2\shared <- directory junction to D:\shared

I have setup GIT repos in D:\project1 and D:\project2 My problem is that GIT seems to only track files in non-junctioned (i.e. real directories).

I use Visual Studio 2015 for both projects, and it's Team Explorer would behave very strangely when project has files from "junctioned" directories:

  • Upon adding a file residing in a directory junction to a project, Team Explorer would only show its parent directory (junction) in the list of changes to commit, not the file itself.
  • Upon committing all changes (i.e. files have been added), Solution Explorer shows all files as being tracked and checked-in (including those that reside in junctions and were not shown in the list of pending changes after they have been added:

git1

  • Editing a file which is shown as checked-in and resides in a junction directory will make it appear to be checked-out:

git2

  • Returning to Team Explorer now, the checked-out file is shown in the list of modified files:

git3

  • However trying to commit it fails with a message: "An error occurred. Detailed message: No changes; nothing to commit."

git4

  • Returning to Solution Explorer the changed file for which commit failed is nonetheless shown as checked-in:

git5

Explicitly adding files that reside in the shared directory (i.e. referencing it via D:\project2\shared\some-shared-file) from outside of Visual Studio using Tortoise GIT for example does not work: add fails with a message that it is both a file and a directory.

git6 git7

The above was done with a new test project where frame directory residing in project's root is really a junction.

In my actual projects however the situation is slightly different... If I browse the repo using Tortoise GIT for example it would actually show the shared files residing in junctions as being tracked and checked-in and part of the repo. However as soon as I open the project in Visual Studio, it would show though same files in Solution Explorer and Team Explorer Changes as "pending delete". So is this a VS quirck?

So the bottom line is I just want to know how can I make files residing in directory junctions to be viewed as part of the project on par with regular files, so that they are properly checked out and checked back in and form part of project's (repo's) history?

Cautery answered 20/6, 2016 at 19:28 Comment(0)
B
6

At present, this is not supported. This is due to a difference in interpretation between junction handling between Git for Windows and libgit2, which is the Git library that is used by Visual Studio and (parts of) TortoiseGit.

It has been decided that both implementations should treat junction points as if they are Unix mount points, however neither implementation actually does that at present.

At present, Git for Windows treats them as if they were normal directories (and so it may delete your junction and replace it with a new directory). libgit2 treats this like a symbolic link, and as a result, Visual Studio refuses to deal with it at all.

Since Microsoft will need to update Visual Studio to fix this, please file a bug at Microsoft Connect and encourage people to vote for it in the hopes that it will get fixed in VS 2015.

Bier answered 20/6, 2016 at 21:56 Comment(5)
Thank you for a clear explanation! Can you recommend any practical workaround perhaps? Or there is none other than to create a "shared" repo and manually commit to it every now and then?Cautery
Perhaps there is some git option to switch? I tired core.symlinks with true and false but that does not seem to do anything.Cautery
I'm afraid that there is no real workaround, you will need to use a shared repository, copy manually, or use a submodule type of approach.Bier
Thank you for the information. Is it still not going to work if I change directory junction to directory symbolic link?Cautery
No - IIRC, there will be no effect in Visual Studio (it's already treating them like symbolic links) while Git for Windows will stop working (since it handles symbolic links differently than junctions). Git refuses to write through symlinks, removing them for security.Bier

© 2022 - 2024 — McMap. All rights reserved.