@@ -949,3 +949,79 @@ void test_checkout_tree__filemode_preserved_in_index(void)
949949 git_index_free (index );
950950}
951951
952+ void test_checkout_tree__case_changing_rename (void )
953+ {
954+ git_index * index ;
955+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT ;
956+ git_oid master_id , dir_commit_id , tree_id , commit_id ;
957+ git_commit * master_commit , * dir_commit ;
958+ git_tree * tree ;
959+ git_signature * signature ;
960+ const git_index_entry * index_entry ;
961+ bool case_sensitive ;
962+
963+ assert_on_branch (g_repo , "master" );
964+
965+ cl_git_pass (git_repository_index (& index , g_repo ));
966+
967+ /* Switch branches and perform a case-changing rename */
968+
969+ opts .checkout_strategy = GIT_CHECKOUT_FORCE ;
970+
971+ cl_git_pass (git_reference_name_to_id (& dir_commit_id , g_repo , "refs/heads/dir" ));
972+ cl_git_pass (git_commit_lookup (& dir_commit , g_repo , & dir_commit_id ));
973+
974+ cl_git_pass (git_checkout_tree (g_repo , (git_object * )dir_commit , & opts ));
975+ cl_git_pass (git_repository_set_head (g_repo , "refs/heads/dir" , NULL , NULL ));
976+
977+ cl_assert (git_path_isfile ("testrepo/README" ));
978+ case_sensitive = !git_path_isfile ("testrepo/readme" );
979+
980+ cl_assert (index_entry = git_index_get_bypath (index , "README" , 0 ));
981+ cl_assert_equal_s ("README" , index_entry -> path );
982+
983+ cl_git_pass (git_index_remove_bypath (index , "README" ));
984+ cl_git_pass (p_rename ("testrepo/README" , "testrepo/__readme__" ));
985+ cl_git_pass (p_rename ("testrepo/__readme__" , "testrepo/readme" ));
986+ cl_git_append2file ("testrepo/readme" , "An addendum..." );
987+ cl_git_pass (git_index_add_bypath (index , "readme" ));
988+
989+ cl_git_pass (git_index_write (index ));
990+
991+ cl_git_pass (git_index_write_tree (& tree_id , index ));
992+ cl_git_pass (git_tree_lookup (& tree , g_repo , & tree_id ));
993+
994+ cl_git_pass (git_signature_new (& signature , "Renamer" , "rename@contoso.com" , time (NULL ), 0 ));
995+
996+ cl_git_pass (git_commit_create (& commit_id , g_repo , "refs/heads/dir" , signature , signature , NULL , "case-changing rename" , tree , 1 , (const git_commit * * )& dir_commit ));
997+
998+ cl_assert (git_path_isfile ("testrepo/readme" ));
999+ if (case_sensitive )
1000+ cl_assert (!git_path_isfile ("testrepo/README" ));
1001+
1002+ cl_assert (index_entry = git_index_get_bypath (index , "readme" , 0 ));
1003+ cl_assert_equal_s ("readme" , index_entry -> path );
1004+
1005+ /* Switching back to master should rename readme -> README */
1006+ opts .checkout_strategy = GIT_CHECKOUT_SAFE ;
1007+
1008+ cl_git_pass (git_reference_name_to_id (& master_id , g_repo , "refs/heads/master" ));
1009+ cl_git_pass (git_commit_lookup (& master_commit , g_repo , & master_id ));
1010+
1011+ cl_git_pass (git_checkout_tree (g_repo , (git_object * )master_commit , & opts ));
1012+ cl_git_pass (git_repository_set_head (g_repo , "refs/heads/master" , NULL , NULL ));
1013+
1014+ assert_on_branch (g_repo , "master" );
1015+
1016+ cl_assert (git_path_isfile ("testrepo/README" ));
1017+ if (case_sensitive )
1018+ cl_assert (!git_path_isfile ("testrepo/readme" ));
1019+
1020+ cl_assert (index_entry = git_index_get_bypath (index , "README" , 0 ));
1021+ cl_assert_equal_s ("README" , index_entry -> path );
1022+
1023+ git_signature_free (signature );
1024+ git_tree_free (tree );
1025+ git_commit_free (dir_commit );
1026+ git_commit_free (master_commit );
1027+ }
0 commit comments