Skip to content

Commit 2fb2091

Browse files
committed
fix: default to creating file-symlinks if it is dangling on Windows (#1354)
This behaviour is the same as in Git.
1 parent 185eb51 commit 2fb2091

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
set -eu -o pipefail
3+
4+
git init -q
5+
6+
target_oid=$(echo "non-existing-target" | git hash-object -w --stdin)
7+
git update-index --index-info <<-EOF
8+
120000 $target_oid dangling
9+
EOF
10+
11+
git commit -m "dangling symlink in index"

gix-worktree-state/tests/state/checkout.rs

+27-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ fn driver_exe() -> String {
4242
exe
4343
}
4444

45+
fn assure_is_empty(dir: impl AsRef<Path>) -> std::io::Result<()> {
46+
assert_eq!(std::fs::read_dir(dir)?.count(), 0);
47+
Ok(())
48+
}
49+
4550
#[test]
4651
fn submodules_are_instantiated_as_directories() -> crate::Result {
4752
let mut opts = opts_from_probe();
@@ -57,11 +62,6 @@ fn submodules_are_instantiated_as_directories() -> crate::Result {
5762
Ok(())
5863
}
5964

60-
fn assure_is_empty(dir: impl AsRef<Path>) -> std::io::Result<()> {
61-
assert_eq!(std::fs::read_dir(dir)?.count(), 0);
62-
Ok(())
63-
}
64-
6565
#[test]
6666
fn accidental_writes_through_symlinks_are_prevented_if_overwriting_is_forbidden() {
6767
let mut opts = opts_from_probe();
@@ -257,6 +257,28 @@ fn symlinks_become_files_if_disabled() -> crate::Result {
257257
Ok(())
258258
}
259259

260+
#[test]
261+
fn dangling_symlinks_can_be_created() -> crate::Result {
262+
let opts = opts_from_probe();
263+
if !opts.fs.symlink {
264+
eprintln!("Skipping dangling symlink test on filesystem that doesn't support it");
265+
return Ok(());
266+
}
267+
268+
let (_source_tree, destination, _index, outcome) =
269+
checkout_index_in_tmp_dir(opts.clone(), "make_dangling_symlink")?;
270+
let worktree_files = dir_structure(&destination);
271+
let worktree_files_stripped = stripped_prefix(&destination, &worktree_files);
272+
273+
assert_eq!(worktree_files_stripped, paths(["dangling"]));
274+
assert!(worktree_files[0]
275+
.symlink_metadata()
276+
.expect("dangling symlink is on disk")
277+
.is_symlink());
278+
assert!(outcome.collisions.is_empty());
279+
Ok(())
280+
}
281+
260282
#[test]
261283
fn allow_or_disallow_symlinks() -> crate::Result {
262284
let mut opts = opts_from_probe();

0 commit comments

Comments
 (0)