@@ -98,3 +98,46 @@ void test_index_racy__write_index_just_after_file(void)
98
98
git_diff_free (diff );
99
99
git_index_free (index );
100
100
}
101
+
102
+ void test_index_racy__empty_file_after_smudge (void )
103
+ {
104
+ git_index * index ;
105
+ git_diff * diff ;
106
+ git_buf path = GIT_BUF_INIT ;
107
+ int i , found_race = 0 ;
108
+ const git_index_entry * entry ;
109
+
110
+ /* Make sure we do have a timestamp */
111
+ cl_git_pass (git_repository_index (& index , g_repo ));
112
+ cl_git_pass (git_index_write (index ));
113
+
114
+ cl_git_pass (git_buf_joinpath (& path , git_repository_workdir (g_repo ), "A" ));
115
+
116
+ /* Make sure writing the file, adding and rewriting happen in the same second */
117
+ for (i = 0 ; i < 10 ; i ++ ) {
118
+ struct stat st ;
119
+ cl_git_mkfile (path .ptr , "A" );
120
+
121
+ cl_git_pass (git_index_add_bypath (index , "A" ));
122
+ cl_git_mkfile (path .ptr , "B" );
123
+ cl_git_pass (git_index_write (index ));
124
+
125
+ cl_git_mkfile (path .ptr , "" );
126
+
127
+ cl_git_pass (p_stat (path .ptr , & st ));
128
+ cl_assert (entry = git_index_get_bypath (index , "A" , 0 ));
129
+ if (entry -> mtime .seconds == (int32_t ) st .st_mtime ) {
130
+ found_race = 1 ;
131
+ break ;
132
+ }
133
+
134
+ }
135
+
136
+ if (!found_race )
137
+ cl_fail ("failed to find race after 10 attempts" );
138
+
139
+ cl_assert_equal_i (0 , entry -> file_size );
140
+
141
+ cl_git_pass (git_diff_index_to_workdir (& diff , g_repo , index , NULL ));
142
+ cl_assert_equal_i (1 , git_diff_num_deltas (diff ));
143
+ }
0 commit comments