Windows permits symbolic links to specify targets with unusual names, such as invalid filenames like ???
and reserved legacy DOS device names like CON
. Cloning a repository on Windows with gix clone
that contains such a symlink fails, due to the error that occurs when attempting to look up metadata for such a target, which is done to figure out if a file symlink or directory symlink should be created.
gix clone
has supported creating dangling symlinks on Windows since 31d02a8 (#1363), which fixed #1354 by special-casing NotFound
errors and falling back to creating a file symlink:
Most cases of dangling symlinks are covered by NotFound
errors. This includes cases where there is no target file at the destination, where there is no destination (e.g., the target path has nonexistent intermediate components), and possibly some other cases where errors prevent the target from being visible. However, this does not cover all errors. When the target is an invalid or reserved name, checkout fails.
Furthermore, it is not only those specific symlinks that are refused; checkout as a whole fails, and gix clone
leaves no cloned directory behind. This can be seen when cloning a repository with a symlink to ???
:
C:\Users\ek\src> gix clone git@github.com:EliahKagan/symlink-to-qmarks.git
18:04:17 indexing done 7.0 objects in 0.00s (30.0k objects/s)
18:04:17 decompressing done 1.5KB in 0.00s (6.3MB/s)
18:04:17 Resolving done 7.0 objects in 0.05s (136.0 objects/s)
18:04:17 Decoding done 1.5KB in 0.05s (29.5KB/s)
18:04:17 writing index file done 1.3KB in 0.00s (8.6MB/s)
18:04:17 create index file done 7.0 objects in 0.06s (115.0 objects/s)
18:04:17 read pack done 1.1KB in 0.10s (10.7KB/s)
Error: IO error while writing blob or reading file metadata or changing filetype
Caused by:
The filename, directory name, or volume label syntax is incorrect. (os error 123)
C:\Users\ek\src> ls symlink-to-qmarks
Get-ChildItem: Cannot find path 'C:\Users\ek\src\symlink-to-qmarks' because it does not exist.
And when cloning a repository with a symlink to CON
:
C:\Users\ek\src> gix clone git@github.com:EliahKagan/symlink-to-con.git
18:09:42 indexing done 7.0 objects in 0.00s (24.6k objects/s)
18:09:42 decompressing done 1.6KB in 0.00s (5.6MB/s)
18:09:42 Resolving done 7.0 objects in 0.05s (136.0 objects/s)
18:09:42 Decoding done 1.6KB in 0.05s (32.2KB/s)
18:09:42 writing index file done 1.3KB in 0.00s (8.3MB/s)
18:09:42 create index file done 7.0 objects in 0.06s (116.0 objects/s)
18:09:42 read pack done 1.2KB in 0.06s (18.5KB/s)
Error: IO error while writing blob or reading file metadata or changing filetype
Caused by:
The parameter is incorrect. (os error 87)
C:\Users\ek\src> ls symlink-to-con
Get-ChildItem: Cannot find path 'C:\Users\ek\src\symlink-to-con' because it does not exist.
More detailed reproduction is presented below.
This is only relevant when gix
operates with a configuration that allows it to create symlinks. When it detects that it cannot create any symlinks at all, or when it is invoked with -c core.symlinks=false
, it creates regular files instead of symlinks, so the behavior described here does not occur. Note that gix
will usually attempt to create symlinks, though, and as of this writing this bug can be observed even when core.symlinks
is set to false
globally, due to #1353.