Skip to content

Commit

Permalink
Test that symlinks to directories are usable
Browse files Browse the repository at this point in the history
At least as `std::fs::metdata` currently works on Windows, this
entails that symlinks to directories on Windows are created as
directory symlinks rather than as file symlinks (since file
symlinks cannot always be automatically dereferenced, and accessing
metadata via the `stat`-like `std::fs::metadata` function is one
situation where that cannot be done).
  • Loading branch information
EliahKagan committed Jun 26, 2024
1 parent cf9e727 commit 93c5b8f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
12 changes: 12 additions & 0 deletions gix-worktree-state/tests/fixtures/make_dir_symlink.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eu -o pipefail

git init -q

target_oid=$(echo -n "." | git hash-object -w --stdin)

git update-index --index-info <<EOF
120000 $target_oid symlink
EOF

git commit -m "symlink in index, points to directory"
28 changes: 28 additions & 0 deletions gix-worktree-state/tests/state/checkout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,34 @@ fn symlinks_become_files_if_disabled() -> crate::Result {
Ok(())
}

#[test]
fn symlinks_to_directories_are_usable() -> crate::Result {
let opts = opts_from_probe();
if !opts.fs.symlink {
eprintln!("Skipping directory symlink test on filesystem that doesn't support it");
return Ok(());
}

let (_source_tree, destination, _index, outcome) =
checkout_index_in_tmp_dir(opts.clone(), "make_dir_symlink", None)?;
let worktree_files = dir_structure(&destination);
let worktree_files_stripped = stripped_prefix(&destination, &worktree_files);

assert_eq!(worktree_files_stripped, paths(["symlink"]));
let symlink_path = &worktree_files[0];
assert!(symlink_path
.symlink_metadata()
.expect("symlink is on disk")
.is_symlink());
assert!(symlink_path
.metadata()
.expect("metadata accessible through symlink")
.is_dir());
assert_eq!(std::fs::read_link(symlink_path)?, Path::new("."));
assert!(outcome.collisions.is_empty());
Ok(())
}

#[test]
fn dangling_symlinks_can_be_created() -> crate::Result {
let opts = opts_from_probe();
Expand Down

0 comments on commit 93c5b8f

Please sign in to comment.