44#include "fileops.h"
55
66git_repository * g_repo = NULL ;
7+ #define TEST_DIR "addall"
78
89void test_index_addall__initialize (void )
910{
@@ -13,6 +14,8 @@ void test_index_addall__cleanup(void)
1314{
1415 git_repository_free (g_repo );
1516 g_repo = NULL ;
17+
18+ cl_fixture_cleanup (TEST_DIR );
1619}
1720
1821#define STATUS_INDEX_FLAGS \
@@ -132,50 +135,59 @@ static void check_stat_data(git_index *index, const char *path, bool match)
132135 }
133136}
134137
138+ static void addall_create_test_repo (bool check_every_step )
139+ {
140+ cl_git_pass (git_repository_init (& g_repo , TEST_DIR , false));
141+ if (check_every_step )
142+ check_status (g_repo , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
143+
144+ cl_git_mkfile (TEST_DIR "/file.foo" , "a file" );
145+ if (check_every_step )
146+ check_status (g_repo , 0 , 0 , 0 , 1 , 0 , 0 , 0 );
147+
148+ cl_git_mkfile (TEST_DIR "/.gitignore" , "*.foo\n" );
149+ if (check_every_step )
150+ check_status (g_repo , 0 , 0 , 0 , 1 , 0 , 0 , 1 );
151+
152+ cl_git_mkfile (TEST_DIR "/file.bar" , "another file" );
153+ if (check_every_step )
154+ check_status (g_repo , 0 , 0 , 0 , 2 , 0 , 0 , 1 );
155+ }
156+
135157void test_index_addall__repo_lifecycle (void )
136158{
137159 int error ;
138160 git_index * index ;
139161 git_strarray paths = { NULL , 0 };
140162 char * strs [1 ];
141163
142- cl_git_pass (git_repository_init (& g_repo , "addall" , false));
143- check_status (g_repo , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
164+ addall_create_test_repo (true);
144165
145166 cl_git_pass (git_repository_index (& index , g_repo ));
146167
147- cl_git_mkfile ("addall/file.foo" , "a file" );
148- check_status (g_repo , 0 , 0 , 0 , 1 , 0 , 0 , 0 );
149-
150- cl_git_mkfile ("addall/.gitignore" , "*.foo\n" );
151- check_status (g_repo , 0 , 0 , 0 , 1 , 0 , 0 , 1 );
152-
153- cl_git_mkfile ("addall/file.bar" , "another file" );
154- check_status (g_repo , 0 , 0 , 0 , 2 , 0 , 0 , 1 );
155-
156168 strs [0 ] = "file.*" ;
157169 paths .strings = strs ;
158170 paths .count = 1 ;
159171
160172 cl_git_pass (git_index_add_all (index , & paths , 0 , NULL , NULL ));
161- check_stat_data (index , "addall /file.bar" , true);
173+ check_stat_data (index , TEST_DIR " /file.bar" , true);
162174 check_status (g_repo , 1 , 0 , 0 , 1 , 0 , 0 , 1 );
163175
164- cl_git_rewritefile ("addall /file.bar" , "new content for file" );
165- check_stat_data (index , "addall /file.bar" , false);
176+ cl_git_rewritefile (TEST_DIR " /file.bar" , "new content for file" );
177+ check_stat_data (index , TEST_DIR " /file.bar" , false);
166178 check_status (g_repo , 1 , 0 , 0 , 1 , 0 , 1 , 1 );
167179
168- cl_git_mkfile ("addall /file.zzz" , "yet another one" );
169- cl_git_mkfile ("addall /other.zzz" , "yet another one" );
170- cl_git_mkfile ("addall /more.zzz" , "yet another one" );
180+ cl_git_mkfile (TEST_DIR " /file.zzz" , "yet another one" );
181+ cl_git_mkfile (TEST_DIR " /other.zzz" , "yet another one" );
182+ cl_git_mkfile (TEST_DIR " /more.zzz" , "yet another one" );
171183 check_status (g_repo , 1 , 0 , 0 , 4 , 0 , 1 , 1 );
172184
173185 cl_git_pass (git_index_update_all (index , NULL , NULL , NULL ));
174- check_stat_data (index , "addall /file.bar" , true);
186+ check_stat_data (index , TEST_DIR " /file.bar" , true);
175187 check_status (g_repo , 1 , 0 , 0 , 4 , 0 , 0 , 1 );
176188
177189 cl_git_pass (git_index_add_all (index , & paths , 0 , NULL , NULL ));
178- check_stat_data (index , "addall /file.zzz" , true);
190+ check_stat_data (index , TEST_DIR " /file.zzz" , true);
179191 check_status (g_repo , 2 , 0 , 0 , 3 , 0 , 0 , 1 );
180192
181193 cl_repo_commit_from_index (NULL , g_repo , NULL , 0 , "first commit" );
@@ -195,27 +207,27 @@ void test_index_addall__repo_lifecycle(void)
195207 /* add with force - should allow */
196208 cl_git_pass (git_index_add_all (
197209 index , & paths , GIT_INDEX_ADD_FORCE , NULL , NULL ));
198- check_stat_data (index , "addall /file.foo" , true);
210+ check_stat_data (index , TEST_DIR " /file.foo" , true);
199211 check_status (g_repo , 1 , 0 , 0 , 3 , 0 , 0 , 0 );
200212
201213 /* now it's in the index, so regular add should work */
202- cl_git_rewritefile ("addall /file.foo" , "new content for file" );
203- check_stat_data (index , "addall /file.foo" , false);
214+ cl_git_rewritefile (TEST_DIR " /file.foo" , "new content for file" );
215+ check_stat_data (index , TEST_DIR " /file.foo" , false);
204216 check_status (g_repo , 1 , 0 , 0 , 3 , 0 , 1 , 0 );
205217
206218 cl_git_pass (git_index_add_all (index , & paths , 0 , NULL , NULL ));
207- check_stat_data (index , "addall /file.foo" , true);
219+ check_stat_data (index , TEST_DIR " /file.foo" , true);
208220 check_status (g_repo , 1 , 0 , 0 , 3 , 0 , 0 , 0 );
209221
210222 cl_git_pass (git_index_add_bypath (index , "more.zzz" ));
211- check_stat_data (index , "addall /more.zzz" , true);
223+ check_stat_data (index , TEST_DIR " /more.zzz" , true);
212224 check_status (g_repo , 2 , 0 , 0 , 2 , 0 , 0 , 0 );
213225
214- cl_git_rewritefile ("addall /file.zzz" , "new content for file" );
226+ cl_git_rewritefile (TEST_DIR " /file.zzz" , "new content for file" );
215227 check_status (g_repo , 2 , 0 , 0 , 2 , 0 , 1 , 0 );
216228
217229 cl_git_pass (git_index_add_bypath (index , "file.zzz" ));
218- check_stat_data (index , "addall /file.zzz" , true);
230+ check_stat_data (index , TEST_DIR " /file.zzz" , true);
219231 check_status (g_repo , 2 , 0 , 1 , 2 , 0 , 0 , 0 );
220232
221233 strs [0 ] = "*.zzz" ;
@@ -228,7 +240,7 @@ void test_index_addall__repo_lifecycle(void)
228240 cl_repo_commit_from_index (NULL , g_repo , NULL , 0 , "second commit" );
229241 check_status (g_repo , 0 , 0 , 0 , 3 , 0 , 0 , 0 );
230242
231- cl_must_pass (p_unlink ("addall /file.zzz" ));
243+ cl_must_pass (p_unlink (TEST_DIR " /file.zzz" ));
232244 check_status (g_repo , 0 , 0 , 0 , 3 , 1 , 0 , 0 );
233245
234246 /* update_all should be able to remove entries */
@@ -240,9 +252,9 @@ void test_index_addall__repo_lifecycle(void)
240252 check_status (g_repo , 3 , 1 , 0 , 0 , 0 , 0 , 0 );
241253
242254 /* must be able to remove at any position while still updating other files */
243- cl_must_pass (p_unlink ("addall /.gitignore" ));
244- cl_git_rewritefile ("addall /file.zzz" , "reconstructed file" );
245- cl_git_rewritefile ("addall /more.zzz" , "altered file reality" );
255+ cl_must_pass (p_unlink (TEST_DIR " /.gitignore" ));
256+ cl_git_rewritefile (TEST_DIR " /file.zzz" , "reconstructed file" );
257+ cl_git_rewritefile (TEST_DIR " /more.zzz" , "altered file reality" );
246258 check_status (g_repo , 3 , 1 , 0 , 1 , 1 , 1 , 0 );
247259
248260 cl_git_pass (git_index_update_all (index , NULL , NULL , NULL ));
@@ -256,3 +268,89 @@ void test_index_addall__repo_lifecycle(void)
256268
257269 git_index_free (index );
258270}
271+
272+ static int addall_match_prefix (
273+ const char * path , const char * matched_pathspec , void * payload )
274+ {
275+ GIT_UNUSED (matched_pathspec );
276+ return !git__prefixcmp (path , payload ) ? 0 : 1 ;
277+ }
278+
279+ static int addall_match_suffix (
280+ const char * path , const char * matched_pathspec , void * payload )
281+ {
282+ GIT_UNUSED (matched_pathspec );
283+ return !git__suffixcmp (path , payload ) ? 0 : 1 ;
284+ }
285+
286+ static int addall_cancel_at (
287+ const char * path , const char * matched_pathspec , void * payload )
288+ {
289+ GIT_UNUSED (matched_pathspec );
290+ return !strcmp (path , payload ) ? -123 : 0 ;
291+ }
292+
293+ void test_index_addall__callback_filtering (void )
294+ {
295+ git_index * index ;
296+
297+ addall_create_test_repo (false);
298+
299+ cl_git_pass (git_repository_index (& index , g_repo ));
300+
301+ cl_git_pass (
302+ git_index_add_all (index , NULL , 0 , addall_match_prefix , "file." ));
303+ check_stat_data (index , TEST_DIR "/file.bar" , true);
304+ check_status (g_repo , 1 , 0 , 0 , 1 , 0 , 0 , 1 );
305+
306+ cl_git_mkfile (TEST_DIR "/file.zzz" , "yet another one" );
307+ cl_git_mkfile (TEST_DIR "/more.zzz" , "yet another one" );
308+ cl_git_mkfile (TEST_DIR "/other.zzz" , "yet another one" );
309+
310+ cl_git_pass (git_index_update_all (index , NULL , NULL , NULL ));
311+ check_stat_data (index , TEST_DIR "/file.bar" , true);
312+ check_status (g_repo , 1 , 0 , 0 , 4 , 0 , 0 , 1 );
313+
314+ cl_git_pass (
315+ git_index_add_all (index , NULL , 0 , addall_match_prefix , "other" ));
316+ check_stat_data (index , TEST_DIR "/other.zzz" , true);
317+ check_status (g_repo , 2 , 0 , 0 , 3 , 0 , 0 , 1 );
318+
319+ cl_git_pass (
320+ git_index_add_all (index , NULL , 0 , addall_match_suffix , ".zzz" ));
321+ check_status (g_repo , 4 , 0 , 0 , 1 , 0 , 0 , 1 );
322+
323+ cl_git_pass (
324+ git_index_remove_all (index , NULL , addall_match_suffix , ".zzz" ));
325+ check_status (g_repo , 1 , 0 , 0 , 4 , 0 , 0 , 1 );
326+
327+ cl_git_fail_with (
328+ git_index_add_all (index , NULL , 0 , addall_cancel_at , "more.zzz" ), -123 );
329+ check_status (g_repo , 3 , 0 , 0 , 2 , 0 , 0 , 1 );
330+
331+ cl_git_fail_with (
332+ git_index_add_all (index , NULL , 0 , addall_cancel_at , "other.zzz" ), -123 );
333+ check_status (g_repo , 4 , 0 , 0 , 1 , 0 , 0 , 1 );
334+
335+ cl_git_pass (
336+ git_index_add_all (index , NULL , 0 , addall_match_suffix , ".zzz" ));
337+ check_status (g_repo , 5 , 0 , 0 , 0 , 0 , 0 , 1 );
338+
339+ cl_must_pass (p_unlink (TEST_DIR "/file.zzz" ));
340+ cl_must_pass (p_unlink (TEST_DIR "/more.zzz" ));
341+ cl_must_pass (p_unlink (TEST_DIR "/other.zzz" ));
342+
343+ cl_git_fail_with (
344+ git_index_update_all (index , NULL , addall_cancel_at , "more.zzz" ), -123 );
345+ /* file.zzz removed from index (so Index Adds 5 -> 4) and
346+ * more.zzz + other.zzz removed (so Worktree Dels 0 -> 2) */
347+ check_status (g_repo , 4 , 0 , 0 , 0 , 2 , 0 , 1 );
348+
349+ cl_git_fail_with (
350+ git_index_update_all (index , NULL , addall_cancel_at , "other.zzz" ), -123 );
351+ /* more.zzz removed from index (so Index Adds 4 -> 3) and
352+ * Just other.zzz removed (so Worktree Dels 2 -> 1) */
353+ check_status (g_repo , 3 , 0 , 0 , 0 , 1 , 0 , 1 );
354+
355+ git_index_free (index );
356+ }
0 commit comments