1 #include "clar_libgit2.h"
4 #include "submodule_helpers.h"
8 static git_repository
*g_repo
= NULL
;
10 void test_submodule_status__initialize(void)
12 g_repo
= setup_fixture_submod2();
15 void test_submodule_status__cleanup(void)
19 void test_submodule_status__unchanged(void)
21 unsigned int status
= get_submodule_status(g_repo
, "sm_unchanged");
22 unsigned int expected
=
23 GIT_SUBMODULE_STATUS_IN_HEAD
|
24 GIT_SUBMODULE_STATUS_IN_INDEX
|
25 GIT_SUBMODULE_STATUS_IN_CONFIG
|
26 GIT_SUBMODULE_STATUS_IN_WD
;
28 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
29 cl_assert(expected
== status
);
32 static void rm_submodule(const char *name
)
34 git_buf path
= GIT_BUF_INIT
;
35 cl_git_pass(git_buf_joinpath(&path
, git_repository_workdir(g_repo
), name
));
36 cl_git_pass(git_futils_rmdir_r(path
.ptr
, NULL
, GIT_RMDIR_REMOVE_FILES
));
37 git_buf_dispose(&path
);
40 static void add_submodule_to_index(const char *name
)
43 cl_git_pass(git_submodule_lookup(&sm
, g_repo
, name
));
44 cl_git_pass(git_submodule_add_to_index(sm
, true));
45 git_submodule_free(sm
);
48 static void rm_submodule_from_index(const char *name
)
53 cl_git_pass(git_repository_index(&index
, g_repo
));
54 cl_assert(!git_index_find(&pos
, index
, name
));
55 cl_git_pass(git_index_remove(index
, name
, 0));
56 cl_git_pass(git_index_write(index
));
57 git_index_free(index
);
60 /* 4 values of GIT_SUBMODULE_IGNORE to check */
62 void test_submodule_status__ignore_none(void)
66 rm_submodule("sm_unchanged");
68 refute_submodule_exists(g_repo
, "just_a_dir", GIT_ENOTFOUND
);
69 refute_submodule_exists(g_repo
, "not-submodule", GIT_EEXISTS
);
70 refute_submodule_exists(g_repo
, "not", GIT_EEXISTS
);
72 status
= get_submodule_status(g_repo
, "sm_changed_index");
73 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
) != 0);
75 status
= get_submodule_status(g_repo
, "sm_changed_head");
76 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
78 status
= get_submodule_status(g_repo
, "sm_changed_file");
79 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
) != 0);
81 status
= get_submodule_status(g_repo
, "sm_changed_untracked_file");
82 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_UNTRACKED
) != 0);
84 status
= get_submodule_status(g_repo
, "sm_missing_commits");
85 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
87 status
= get_submodule_status(g_repo
, "sm_added_and_uncommited");
88 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_ADDED
) != 0);
90 /* removed sm_unchanged for deleted workdir */
91 status
= get_submodule_status(g_repo
, "sm_unchanged");
92 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_DELETED
) != 0);
94 /* now mkdir sm_unchanged to test uninitialized */
95 cl_git_pass(git_futils_mkdir_relative("sm_unchanged", "submod2", 0755, 0, NULL
));
96 status
= get_submodule_status(g_repo
, "sm_unchanged");
97 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
) != 0);
99 /* update sm_changed_head in index */
100 add_submodule_to_index("sm_changed_head");
101 status
= get_submodule_status(g_repo
, "sm_changed_head");
102 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_MODIFIED
) != 0);
104 /* remove sm_changed_head from index */
105 rm_submodule_from_index("sm_changed_head");
106 status
= get_submodule_status(g_repo
, "sm_changed_head");
107 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_DELETED
) != 0);
110 void test_submodule_status__ignore_untracked(void)
113 git_submodule_ignore_t ign
= GIT_SUBMODULE_IGNORE_UNTRACKED
;
115 rm_submodule("sm_unchanged");
117 refute_submodule_exists(g_repo
, "just_a_dir", GIT_ENOTFOUND
);
118 refute_submodule_exists(g_repo
, "not-submodule", GIT_EEXISTS
);
119 refute_submodule_exists(g_repo
, "not", GIT_EEXISTS
);
121 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_index", ign
));
122 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
) != 0);
124 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
125 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
127 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_file", ign
));
128 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
) != 0);
130 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_untracked_file", ign
));
131 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
133 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_missing_commits", ign
));
134 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
136 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_added_and_uncommited", ign
));
137 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_ADDED
) != 0);
139 /* removed sm_unchanged for deleted workdir */
140 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
141 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_DELETED
) != 0);
143 /* now mkdir sm_unchanged to test uninitialized */
144 cl_git_pass(git_futils_mkdir_relative("sm_unchanged", "submod2", 0755, 0, NULL
));
145 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
146 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
) != 0);
148 /* update sm_changed_head in index */
149 add_submodule_to_index("sm_changed_head");
150 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
151 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_MODIFIED
) != 0);
154 void test_submodule_status__ignore_dirty(void)
157 git_submodule_ignore_t ign
= GIT_SUBMODULE_IGNORE_DIRTY
;
159 rm_submodule("sm_unchanged");
161 refute_submodule_exists(g_repo
, "just_a_dir", GIT_ENOTFOUND
);
162 refute_submodule_exists(g_repo
, "not-submodule", GIT_EEXISTS
);
163 refute_submodule_exists(g_repo
, "not", GIT_EEXISTS
);
165 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_index", ign
));
166 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
168 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
169 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
171 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_file", ign
));
172 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
174 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_untracked_file", ign
));
175 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
177 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_missing_commits", ign
));
178 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_MODIFIED
) != 0);
180 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_added_and_uncommited", ign
));
181 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_ADDED
) != 0);
183 /* removed sm_unchanged for deleted workdir */
184 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
185 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_DELETED
) != 0);
187 /* now mkdir sm_unchanged to test uninitialized */
188 cl_git_pass(git_futils_mkdir_relative("sm_unchanged", "submod2", 0755, 0, NULL
));
189 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
190 cl_assert((status
& GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
) != 0);
192 /* update sm_changed_head in index */
193 add_submodule_to_index("sm_changed_head");
194 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
195 cl_assert((status
& GIT_SUBMODULE_STATUS_INDEX_MODIFIED
) != 0);
198 void test_submodule_status__ignore_all(void)
201 git_submodule_ignore_t ign
= GIT_SUBMODULE_IGNORE_ALL
;
203 rm_submodule("sm_unchanged");
205 refute_submodule_exists(g_repo
, "just_a_dir", GIT_ENOTFOUND
);
206 refute_submodule_exists(g_repo
, "not-submodule", GIT_EEXISTS
);
207 refute_submodule_exists(g_repo
, "not", GIT_EEXISTS
);
209 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_index", ign
));
210 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
212 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
213 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
215 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_file", ign
));
216 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
218 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_untracked_file", ign
));
219 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
221 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_missing_commits", ign
));
222 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
224 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_added_and_uncommited", ign
));
225 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
227 /* removed sm_unchanged for deleted workdir */
228 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
229 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
231 /* now mkdir sm_unchanged to test uninitialized */
232 cl_git_pass(git_futils_mkdir_relative("sm_unchanged", "submod2", 0755, 0, NULL
));
233 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_unchanged", ign
));
234 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
236 /* update sm_changed_head in index */
237 add_submodule_to_index("sm_changed_head");
238 cl_git_pass(git_submodule_status(&status
, g_repo
,"sm_changed_head", ign
));
239 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
246 } submodule_expectations
;
248 static int confirm_submodule_status(
249 const char *path
, unsigned int status_flags
, void *payload
)
251 submodule_expectations
*exp
= payload
;
253 while (exp
->statuses
[exp
->counter
] < 0)
256 cl_assert_equal_i(exp
->statuses
[exp
->counter
], (int)status_flags
);
257 cl_assert_equal_s(exp
->paths
[exp
->counter
++], path
);
259 GIT_UNUSED(status_flags
);
264 void test_submodule_status__iterator(void)
267 git_iterator_options iter_opts
= GIT_ITERATOR_OPTIONS_INIT
;
268 const git_index_entry
*entry
;
270 static const char *expected
[] = {
273 "just_a_dir/contents",
276 "not-submodule/README.txt",
280 "sm_added_and_uncommited",
284 "sm_changed_untracked_file",
285 "sm_missing_commits",
289 static int expected_flags
[] = {
290 GIT_STATUS_INDEX_MODIFIED
| GIT_STATUS_WT_MODIFIED
, /* ".gitmodules" */
291 -1, /* "just_a_dir/" will be skipped */
292 GIT_STATUS_CURRENT
, /* "just_a_dir/contents" */
293 GIT_STATUS_CURRENT
, /* "just_a_file" */
294 GIT_STATUS_WT_NEW
, /* "not-submodule/" untracked item */
295 -1, /* "not-submodule/README.txt" */
296 GIT_STATUS_WT_NEW
, /* "not/" untracked item */
297 -1, /* "not/README.txt" */
298 GIT_STATUS_CURRENT
, /* "README.txt */
299 GIT_STATUS_INDEX_NEW
, /* "sm_added_and_uncommited" */
300 GIT_STATUS_WT_MODIFIED
, /* "sm_changed_file" */
301 GIT_STATUS_WT_MODIFIED
, /* "sm_changed_head" */
302 GIT_STATUS_WT_MODIFIED
, /* "sm_changed_index" */
303 GIT_STATUS_WT_MODIFIED
, /* "sm_changed_untracked_file" */
304 GIT_STATUS_WT_MODIFIED
, /* "sm_missing_commits" */
305 GIT_STATUS_CURRENT
, /* "sm_unchanged" */
308 submodule_expectations exp
= { 0, expected
, expected_flags
};
309 git_status_options opts
= GIT_STATUS_OPTIONS_INIT
;
312 iter_opts
.flags
= GIT_ITERATOR_IGNORE_CASE
| GIT_ITERATOR_INCLUDE_TREES
;
314 cl_git_pass(git_repository_index(&index
, g_repo
));
315 cl_git_pass(git_iterator_for_workdir(&iter
, g_repo
, index
, NULL
, &iter_opts
));
317 for (i
= 0; !git_iterator_advance(&entry
, iter
); ++i
)
318 cl_assert_equal_s(expected
[i
], entry
->path
);
320 git_iterator_free(iter
);
321 git_index_free(index
);
323 opts
.flags
= GIT_STATUS_OPT_INCLUDE_UNTRACKED
|
324 GIT_STATUS_OPT_INCLUDE_UNMODIFIED
|
325 GIT_STATUS_OPT_INCLUDE_IGNORED
|
326 GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
|
327 GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY
;
329 cl_git_pass(git_status_foreach_ext(
330 g_repo
, &opts
, confirm_submodule_status
, &exp
));
333 void test_submodule_status__untracked_dirs_containing_ignored_files(void)
335 unsigned int status
, expected
;
338 "submod2/.git/modules/sm_unchanged/info/exclude", "\n*.ignored\n");
341 git_futils_mkdir_relative("sm_unchanged/directory", "submod2", 0755, 0, NULL
));
343 "submod2/sm_unchanged/directory/i_am.ignored",
344 "ignore this file, please\n");
346 status
= get_submodule_status(g_repo
, "sm_unchanged");
347 cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status
));
349 expected
= GIT_SUBMODULE_STATUS_IN_HEAD
|
350 GIT_SUBMODULE_STATUS_IN_INDEX
|
351 GIT_SUBMODULE_STATUS_IN_CONFIG
|
352 GIT_SUBMODULE_STATUS_IN_WD
;
353 cl_assert(status
== expected
);