threads / bug / 61417

[Bug Report] git config includeIf not traversing symlink subdirectories

Subject: [Bug Report] git config includeIf not traversing symlink subdirectories

## tl;dr

3 messages between May 3, 2024 and May 4, 2024.

replies: 2people: 2as markdown or json

Simon Thurston· May 3, 2024, 21:31 UTC · lore

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue) On Windows. Create a directory. Configre a gitconfig file to includeIf gitdir that directory. Add any configuration you wish to the gitconfig file pointed to by the includeif path. Inside the created directory, create a symlink to a UNC Path/Network location. Change directory into the symlinked directory. Run git config --show-origin on a configured value.

What did you expect to happen? (Expected behavior) The value configured in the includeIf path to be found.

What happened instead? (Actual behavior) No configuration data found.

What's different between what you expected and what actually happened? Git seems to be unable to traverse subdirectories that are symlinks to include any git repositories stored inside them.

Anything else you want to add: I am well aware that while running Windows 11 in a corporate environment there is likely something silly that is stopping me from doing something correctly within our Group Policy. However, I just wanted to open a report in case that something is not working. The workaround I had to do for this is to regular include the config file I had written, which is not ideal, even though I am pretty sure that the includeIfs I have after it should override it. I am interacting with git through pwsh 7.4.2.

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info] git version: git version 2.45.0.windows.1 cpu: x86_64 built from commit: b5d0511969ccd9ab86395c37e5a7619d8b4e7c32 sizeof-long: 4 sizeof-size_t: 8 shell-path: /bin/sh feature: fsmonitor--daemon uname: Windows 10.0 22635 compiler info: gnuc: 13.2 libc info: no libc information available $SHELL (typically, interactive shell): <unset>

[Enabled Hooks]
brian m. carlson· May 3, 2024, 23:06 UTC · re: Simon Thurston · lore

Re: [Bug Report] git config includeIf not traversing symlink subdirectories

On 2024-05-03 at 21:31:59, Simon Thurston wrote:
Show 10 quoted lines
> Thank you for filling out a Git bug report!
> Please answer the following questions to help us understand your issue.
> 
> What did you do before the bug happened? (Steps to reproduce your issue)
> On Windows. Create a directory. Configre a gitconfig file to includeIf
> gitdir that directory. Add any configuration you wish to the gitconfig
> file pointed to by the includeif path. Inside the created directory,
> create a symlink to a UNC Path/Network location. Change directory into
> the symlinked directory. Run git config --show-origin on a configured
> value.

I've included a shell script below that tries to provide a testcase for your reproduction steps. Since I'm on Linux, I don't have a UNC drive, but I created a different location outside of the repository called other-dir that simulates the same behaviour:

---- #!/bin/sh

tempdir=$(mktemp -d)
cd "$tempdir"
cat >config <<EOM
[includeIf "gitdir:$tempdir/dir/"]
    path = "$tempdir/other-config"
EOM
cat >other-config <<EOM
[user]
    name = "Foo Bar"
EOM

export GIT_CONFIG_GLOBAL="$tempdir/config" mkdir "$tempdir/dir" mkdir "$tempdir/other-dir" cd "$tempdir/dir" git init -b dev echo "In dir ($PWD):" git config -l --show-origin ln -s ../other-dir other-dir cd other-dir echo "In symlink ($PWD):" git config -l --show-origin ----

Show 9 quoted lines
> What did you expect to happen? (Expected behavior)
> The value configured in the includeIf path to be found.
> 
> What happened instead? (Actual behavior)
> No configuration data found.
> 
> What's different between what you expected and what actually happened?
> Git seems to be unable to traverse subdirectories that are symlinks to
> include any git repositories stored inside them.

Assuming my reproduction steps are correct, this is expected. Git always determines the Git directory by resolving it to an absolute path containing no symlinks with the equivalent of `realpath` on Linux or `GetFinalPathNameByHandle` on Windows. The fact that your working directory contains a symlink doesn't mean that the destination of the symlink is part of your repository. In fact, if the destination of your symlink is on another drive, it cannot be in your repository at all, since Git cannot handle cross-drive repositories at all. Since it's not in the repository, the gitdir pattern won't match.

If I've misunderstood, could you help me understand better by providing a small shell script that can reproduce the problem you're seeing, so I can provide a better answer?

-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA
brian m. carlson· May 4, 2024, 01:06 UTC · lore

Re: [Bug Report] git config includeIf not traversing symlink subdirectories

[Please keep the list in CC so others can chime in.]
On 2024-05-03 at 23:41:14, Simon Thurston wrote:
Show 5 quoted lines
> Thanks Brian. The issue I'm having is that I have two main development directories, for "home" and for "work". I have includeIf statements in my primary .gitconfig that sources different public/private keys for each subdirectory. Under the "work" subdirectory, I have folders for projects, and then a "Deploy" folder that contains symlinks to folders over the network, so I can quickly cd and git clone/pull to deploy things manually, as well as use with some CD powershell scripts I have. The important thing to note is that the directories that are symlinked to repositories.
> 
> In short, if I have an includeIf that encompasses a parent directory, any subdirectory symlink that points to a repository on a local server does not properly resolve to include the settings from the includeIf.
> 
> /work/Project/.git can be detected, but /work/Deploy/ProjectSymlink/.git cannot, and thus any includeIf statement that checks for repositories under /work/** does not properly detect the repositories that are symlinked.

Yes, I think this is intentional. Git doesn't consider the repositories which are on the UNC drive to be under /work/Deploy, because the canonical path is not in that location.

> I have tried to get around this by adding an extra includeIf statement to include //the/direct/unc/path/** but that was not able to resolve properly either. Mapped network drives with drive letters also don't resolve, and the only workaround I had was to blanket apply the config file to every directory, which is not ideal for the environment I work in.

Yes, the mapped network drives will be resolved to the UNC path with `GetPathNameByHandle`, which is why that syntax doesn't work.

> If the behavior around symlinks is intentional, then that is fine and can be worked around, but not being able to specify UNC style paths in the configs is something that makes it difficult to work on SMB shares with specific configs needed.

As I said, I don't use Windows except extremely incidentally, so it's difficult for me to speak with any authority on UNC paths. It's possible that they are supported using a syntax I don't know about, or it's possible that they simply don't work at all. If it's the latter, I'm sure we'd accept a patch to fix it.

What I might suggest is switching into one of the symlinked directories and running `git rev-parse --absolute-git-dir`, which should show you what Git thinks the directory is. You can then write that path directly in the configuration file, nothing that inside the double quotes, backslashes must be escaped (so if the path is \\the\direct\unc\path, you'd write '[includeIf "\\\\the\\direct\\unc\\path"]'). You may also want to use gitdir/i if you're not already, since my guess is that your paths are actually case-insensitive.

If that doesn't work, hopefully someone else more familiar than me with Windows can speak more to this.

-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA

← back to recent threads