@@ -8,27 +8,19 @@ mod checkout {
88
99 use git_object:: bstr:: ByteSlice ;
1010 use git_odb:: FindExt ;
11+ use git_worktree:: fs:: Capabilities ;
1112 use git_worktree:: index;
12- use git_worktree:: index:: checkout:: Options ;
1313 use tempfile:: TempDir ;
1414
1515 use crate :: fixture_path;
1616
17- #[ test]
18- fn allow_symlinks ( ) -> crate :: Result {
19- let opts = opts_with_symlink ( true ) ;
20- if !git_worktree:: fs:: Capabilities :: probe ( std:: env:: current_dir ( ) ?. join ( ".." ) . join ( ".git" ) ) . symlink {
21- eprintln ! ( "IGNORING symlink test on file system without symlink support" ) ;
22- // skip if symlinks aren't supported anyway.
23- return Ok ( ( ) ) ;
24- } ;
25- let ( source_tree, destination) = setup_fixture_with_options ( opts, "make_mixed_without_submodules" ) ?;
26-
27- assert_equality ( & source_tree, & destination, opts. fs . symlink ) ?;
28- Ok ( ( ) )
17+ fn probe_gitoxide_dir ( ) -> crate :: Result < Capabilities > {
18+ Ok ( git_worktree:: fs:: Capabilities :: probe (
19+ std:: env:: current_dir ( ) ?. join ( ".." ) . join ( ".git" ) ,
20+ ) )
2921 }
3022
31- fn opts_with_symlink ( symlink : bool ) -> Options {
23+ fn opts_with_symlink ( symlink : bool ) -> index :: checkout :: Options {
3224 index:: checkout:: Options {
3325 fs : git_worktree:: fs:: Capabilities {
3426 symlink,
@@ -41,14 +33,67 @@ mod checkout {
4133 #[ test]
4234 fn symlinks_become_files_if_disabled ( ) -> crate :: Result {
4335 let opts = opts_with_symlink ( false ) ;
44- let ( source_tree, destination) = setup_fixture_with_options ( opts, "make_mixed_without_submodules" ) ?;
36+ let ( source_tree, destination, _index ) = checkout_index_in_tmp_dir ( opts, "make_mixed_without_submodules" ) ?;
4537
4638 assert_equality ( & source_tree, & destination, opts. fs . symlink ) ?;
4739
4840 Ok ( ( ) )
4941 }
5042
51- fn assert_equality ( source_tree : & Path , destination : & TempDir , allow_symlinks : bool ) -> crate :: Result {
43+ #[ test]
44+ fn allow_symlinks ( ) -> crate :: Result {
45+ let opts = opts_with_symlink ( true ) ;
46+ if !probe_gitoxide_dir ( ) ?. symlink {
47+ eprintln ! ( "IGNORING symlink test on file system without symlink support" ) ;
48+ // skip if symlinks aren't supported anyway.
49+ return Ok ( ( ) ) ;
50+ } ;
51+ let ( source_tree, destination, _index) = checkout_index_in_tmp_dir ( opts, "make_mixed_without_submodules" ) ?;
52+
53+ assert_equality ( & source_tree, & destination, opts. fs . symlink ) ?;
54+ Ok ( ( ) )
55+ }
56+
57+ #[ test]
58+ fn no_case_related_collisions_on_case_sensitive_filesystem ( ) {
59+ if probe_gitoxide_dir ( ) . unwrap ( ) . ignore_case {
60+ eprintln ! ( "Skipping case-sensitive testing on what would be a case-insenstive file system" ) ;
61+ return ;
62+ }
63+ let opts = opts_with_symlink ( true ) ;
64+ let ( source_tree, destination, index) = checkout_index_in_tmp_dir ( opts, "make_ignorecase_collisions" ) . unwrap ( ) ;
65+ assert_eq ! ( index. entries( ) . len( ) , 2 , "there is just one colliding item" ) ;
66+
67+ let num_files = assert_equality ( & source_tree, & destination, opts. fs . symlink ) . unwrap ( ) ;
68+ assert_eq ! ( num_files, index. entries( ) . len( ) , "it checks out all files" ) ;
69+ }
70+
71+ #[ test]
72+ fn collisions_are_detected_on_a_case_sensitive_filesystem ( ) {
73+ if !probe_gitoxide_dir ( ) . unwrap ( ) . ignore_case {
74+ eprintln ! ( "Skipping case-insensitive testing on what would be a case-senstive file system" ) ;
75+ return ;
76+ }
77+ let opts = opts_with_symlink ( true ) ;
78+ let ( source_tree, destination, index) = checkout_index_in_tmp_dir ( opts, "make_ignorecase_collisions" ) . unwrap ( ) ;
79+ assert_eq ! ( index. entries( ) . len( ) , 2 , "there is just one colliding item" ) ;
80+
81+ let source_files = dir_structure ( & source_tree) ;
82+ assert_eq ! (
83+ stripped_prefix( & source_tree, & source_files) ,
84+ vec![ PathBuf :: from( "a" ) ] ,
85+ "the source also only contains the first created file"
86+ ) ;
87+
88+ let dest_files = dir_structure ( & destination) ;
89+ assert_eq ! (
90+ stripped_prefix( & destination, & dest_files) ,
91+ vec![ PathBuf :: from( "A" ) ] ,
92+ "it only creates the first file of a collision"
93+ ) ;
94+ }
95+
96+ fn assert_equality ( source_tree : & Path , destination : & TempDir , allow_symlinks : bool ) -> crate :: Result < usize > {
5297 let source_files = dir_structure ( source_tree) ;
5398 let worktree_files = dir_structure ( & destination) ;
5499
@@ -57,7 +102,9 @@ mod checkout {
57102 stripped_prefix( & destination, & worktree_files) ,
58103 ) ;
59104
105+ let mut count = 0 ;
60106 for ( source_file, worktree_file) in source_files. iter ( ) . zip ( worktree_files. iter ( ) ) {
107+ count += 1 ;
61108 if !allow_symlinks && source_file. is_symlink ( ) {
62109 assert ! ( !worktree_file. is_symlink( ) ) ;
63110 assert_eq ! ( fs:: read( worktree_file) ?. to_path( ) ?, fs:: read_link( source_file) ?) ;
@@ -71,7 +118,7 @@ mod checkout {
71118 ) ;
72119 }
73120 }
74- Ok ( ( ) )
121+ Ok ( count )
75122 }
76123
77124 pub fn dir_structure < P : AsRef < std:: path:: Path > > ( path : P ) -> Vec < std:: path:: PathBuf > {
@@ -87,10 +134,10 @@ mod checkout {
87134 files
88135 }
89136
90- fn setup_fixture_with_options (
91- opts : git_worktree :: index:: checkout:: Options ,
137+ fn checkout_index_in_tmp_dir (
138+ opts : index:: checkout:: Options ,
92139 name : & str ,
93- ) -> crate :: Result < ( PathBuf , TempDir ) > {
140+ ) -> crate :: Result < ( PathBuf , TempDir , git_index :: File ) > {
94141 let source_tree = fixture_path ( name) ;
95142 let git_dir = source_tree. join ( ".git" ) ;
96143 let mut index = git_index:: File :: at ( git_dir. join ( "index" ) , Default :: default ( ) ) ?;
@@ -103,7 +150,7 @@ mod checkout {
103150 move |oid, buf| odb. find_blob ( oid, buf) . ok ( ) ,
104151 opts,
105152 ) ?;
106- Ok ( ( source_tree, destination) )
153+ Ok ( ( source_tree, destination, index ) )
107154 }
108155
109156 fn stripped_prefix ( prefix : impl AsRef < Path > , source_files : & [ PathBuf ] ) -> Vec < & Path > {
0 commit comments