Search code examples
windowsgitsymlink

git (windows): how to get information if a file in repo (in git objects?) is a symlink or not


I have several symbolic links (file and directory links) in my repository.

When I clone the repository it depends if the destination file system is able to handle symbolic links or not.
When it's not able to handle symbolic links (e.g. at a SMB network drive) I clone it with "-c core.symlinks=false".
In that case git stores the symbolic links in the checkout as regular text files where the content is where it normally links to.

I need to detect this in a post-checkout hook which should check if all the symbolic links in the repository are also links in the current checkout.
For that I somehow need to detect which git objects / git files in the repo (the current branch) are defined as symbolic links but are not in the filesystem.

I made experiments to get information about the repository files with "git ls-files", "git ls-remote", "git ls-tree" together with "git cat-file" and other plumb commands...

But I was not successful detecting the type of an object / file.

Even when I do a "git diff" for a known symbolic link it says that there are no differences...

Is it somehow possible to detect if a file in the repo should be a symbolic link but is not in the current checkout / file system?
How can I loop over all repo objects of a certain type (e.g. all files, all symlinks, all dirs)?


Solution

  • Symbolic links are stored as files with a special mode. The first column of git ls-tree shows an octal number that works like the Unix/Linux stat().st_mode field – the high 4 bits represent the type while the low 12 bits are the permissions. Regular files have type 10 octal, while symbolic links are type 12.

    There is no distinction between "file" and "directory" symlinks in Unix/Linux so that is not stored in the repository either. Git for Windows has to guess that during checkout. (Sometimes directory symlinks have a trailing / as part of the target text, but that's not guaranteed.)