Skip to content

Commit 1e81220

Browse files
committed
fix: Always fall back to creating file symlinks on Windows
When the metadata of a symlink's target cannot be obtained, even if the error is something other than `NotFound`, this falls back to creating file symbolic links. This only affects scenarios where either the checkout would fail entirely or where the symlink would have been treated as a collision and skipped (even though it was not really a collision, since only its target had an error). Other cases are not affected, and all exisitng scenarios where directory symlink would be created will still create directory symlinks. This builds on 31d02a8 (#1363) by supporting dangling symlinks even when the target filenames are unusual, such as when the name is invalid or reserved. Windows permits such symlinks to be created, and going ahead and creating the matches the Git behavior. This should also support other errors beisdes `NotFound`. For example, some permissions-related errors, in some cases where traversal or acccess (even to access metadata) are not allowed, would fail to create a symlink. This should address that as well. This works by using `Path::is_dir()` in the standard library, which automatically converts all errors (not just `NotFound`) into `false`. The logic here is thus quite similar to what was already present, just more tolerant, even though the code itself is shorter and simpler. This fixes #1420, and also fixes #1421.
1 parent fb1e614 commit 1e81220

File tree

1 file changed

+1
-6
lines changed

1 file changed

+1
-6
lines changed

gix-fs/src/symlink.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ pub fn create(original: &Path, link: &Path) -> io::Result<()> {
4141
use std::os::windows::fs::{symlink_dir, symlink_file};
4242
// TODO: figure out if links to links count as files or whatever they point at
4343
let orig_abs = link.parent().expect("dir for link").join(original);
44-
let is_dir = match std::fs::metadata(orig_abs) {
45-
Ok(m) => m.is_dir(),
46-
Err(err) if err.kind() == io::ErrorKind::NotFound => false,
47-
Err(err) => return Err(err),
48-
};
49-
if is_dir {
44+
if orig_abs.is_dir() {
5045
symlink_dir(original, link)
5146
} else {
5247
symlink_file(original, link)

0 commit comments

Comments
 (0)