gix clone
sets core.symlinks
to false
on Windows even if globally true
#1353
Labels
acknowledged
an issue is accepted as shortcoming to be fixed
C-Windows
Windows-specific issues
help wanted
Extra attention is needed
Current behavior 馃槸
On Windows,
core.symlinks
is intended to tofalse
when not set, and in some installations is even set asfalse
in the installation scope. Changing it, if done, is most often done in the global scope, such as by runninggit config --global core.symlinks true
.But
gix clone
does not honor this, instead checking out regular-file stubs rather than symlinks even on such a Windows system.gix clone
furthermore setscore.symlinks
tofalse
explicitly in the newly cloned repository's.git/config
. This happens even when the user is able to create symbolic links (without having to elevate privileges to do so via UAC or any other mechanism).When
-c core.symlinks=true
is passed togix
, the clone will create the symlinks. But even in that case,gix
sets a localfalse
value for it in.git/config
. Thus the problem appears to be that local value, which rightly overrides the global value, but is wrongly created in the first place (or at least is wrongly set tofalse
even when it should not).(This may or may not be readily checkable on CI without special effort, since the Windows runners for GitHub Actions customize
core.symlinks
, setting it totrue
for the installation, at installation time.)Expected behavior 馃
When
core.symlinks
is set totrue
explicitly.gix clone
should attempt to check out symbolic links as symbolic links rather than as regular files.If falling back to checking out regular files is an intended behavior, then when
core.symlinks
is set totrue
this fallback should either be disabled or should be done only based on the failure of an actual attempt to create a symbolic link, or based on a precise check of the running process's abilities. (A precise pre-check done without attempting symlink creation would not be straightforward, since this is affected by multiple settings in Windows, and not all documentation covers all of them.)This entails that
gix
should not always automatically setcore.symlinks
tofalse
in newly cloned repositories' local configuration, but either should never do that, or (though this would be more complex) should only do it in scenarios where it is consistent with the existing Git configuration and user account abilities.Git behavior
Git will check out symlinks as actual Windows symbolic links rather than as regular-file stubs, including in commands such as
git clone
.Steps to reproduce 馃暪
Make the test repository
Create a repository with a symbolic link. For simplicity, it should be a symbolic link to a regular file in the repository, and thus not dangling/broken. (Besides simplicity, this also avoids confusion relating to the separate issue #1354.) This can be done with Git either on Windows or on a Unix-like system; I used Ubuntu, pushed to a remote, and cloned from a remote, to ensure that this bug was not specific to
file://
remotes.Alternatively, the has-symlink repository may be used. It was created that way (then minimal documentation was added in a second commit). It is used in the instructions below, which assume that either PowerShell or Git Bash is used.
Set
core.symlinks
globally and/or check that it is setOn a Windows system, run this command, at least if that has not already been done in your user account:
Checking that it is set in the global scope by running
git config core.symlinks
should showtrue
.Clone with
gix clone
and inspect the repositoryClone the repository with
gix
:The clone succeeds, but inspecting the checked out files reveals that
symlink
is actually a regular file rather than a symbolic link. Run:In PowerShell, that shows output like:
To verify that
gix
setcore.symlinks
tofalse
in the local configuration, inspecthas-symlink/.git/config
, or run this command, which outputsfalse
:Redo the clone with
core.symlinks
set in the commandTo see how this differs from the behavior of
gix
whencore.symlinks
is provided on the command line, first delete the cloned repository:rm -rf has-symlink
rm -r -fo has-symlink
Then try the clone again, but this time use the
-c
option togix
:Check the
symlink
entry again:This time, that shows that it really is a symlink on disk. For example, in PowerShell, it looks like:
However, it has still set
core.symlinks
tofalse
in the newly cloned repository's local configuration. This still outputsfalse
:Thus the reason
-c
behaved differently was that it overrode the wrongly setfalse
value thatgix
placed at repository level. Furthermore, using-c
is an insufficient workaround because it is still set otherwise locally (though unsetting it locally after cloning it that way should be a sufficient workaround until a fix is available).Optionally, compare to the behavior of Git
Deleting the cloned repository again and cloning it with
git clone
rather thangix clone
shows the expected behavior (and-c
does not need to be used). After doing that,ls -l has-symlink/symlink
shows thatsymlink
is created as a symlink, andgit -C has-symlink config --local core.symlinks
shows no output (sincegit clone
does not set a local value forcore.symlinks
when cloning).Optionally, verify that other global configuration is honored
The problem is not that
gix
doesn't use global configuration in general. I verified this by temporarily breakingssh
forgit
andgix
by running:Then I attempted to clone a repository that I know I can otherwise clone with
gix
:As expected, this attempted to use the bogus
foo
implementation of SSH:To undo that, simply run:
The text was updated successfully, but these errors were encountered: