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).

This fixes GitoxideLabs#1422. Note that this issue pertains solely to what the
test suite covers; the issue is not a bug in the code under test,
and this commit does not modify the code under test.
  • Loading branch information
EliahKagan committed Jun 26, 2024
1 parent 1e81220 commit fbc51df
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 fbc51df

Please sign in to comment.