From d52cbf221832ccfca482a73947d411b19d0dea83 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Wed, 26 Jun 2024 00:53:30 -0400 Subject: [PATCH] Test that symlinks to directories are usable 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 #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. --- .../tests/fixtures/make_dir_symlink.sh | 12 ++++++++ gix-worktree-state/tests/state/checkout.rs | 28 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100755 gix-worktree-state/tests/fixtures/make_dir_symlink.sh diff --git a/gix-worktree-state/tests/fixtures/make_dir_symlink.sh b/gix-worktree-state/tests/fixtures/make_dir_symlink.sh new file mode 100755 index 00000000000..e0acd233ab3 --- /dev/null +++ b/gix-worktree-state/tests/fixtures/make_dir_symlink.sh @@ -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 < 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();