1 #include "clar_libgit2.h"
4 #include "submodule_helpers.h"
6 static git_repository
*g_repo
= NULL
;
8 #define SM_LIBGIT2_URL "https://github.com/libgit2/libgit2.git"
9 #define SM_LIBGIT2 "sm_libgit2"
10 #define SM_LIBGIT2B "sm_libgit2b"
12 void test_submodule_modify__initialize(void)
14 g_repo
= setup_fixture_submod2();
17 void test_submodule_modify__add(void)
23 /* re-add existing submodule */
26 git_submodule_add_setup(NULL
, g_repo
, "whatever", "sm_unchanged", 1));
28 /* add a submodule using a gitlink */
31 git_submodule_add_setup(&sm
, g_repo
, SM_LIBGIT2_URL
, SM_LIBGIT2
, 1)
33 git_submodule_free(sm
);
35 cl_assert(git_path_isfile("submod2/" SM_LIBGIT2
"/.git"));
37 cl_assert(git_path_isdir("submod2/.git/modules"));
38 cl_assert(git_path_isdir("submod2/.git/modules/" SM_LIBGIT2
));
39 cl_assert(git_path_isfile("submod2/.git/modules/" SM_LIBGIT2
"/HEAD"));
41 cl_git_pass(git_repository_config(&cfg
, g_repo
));
43 git_config_get_string(&s
, cfg
, "submodule." SM_LIBGIT2
".url"));
44 cl_assert_equal_s(s
, SM_LIBGIT2_URL
);
47 /* add a submodule not using a gitlink */
50 git_submodule_add_setup(&sm
, g_repo
, SM_LIBGIT2_URL
, SM_LIBGIT2B
, 0)
52 git_submodule_free(sm
);
54 cl_assert(git_path_isdir("submod2/" SM_LIBGIT2B
"/.git"));
55 cl_assert(git_path_isfile("submod2/" SM_LIBGIT2B
"/.git/HEAD"));
56 cl_assert(!git_path_exists("submod2/.git/modules/" SM_LIBGIT2B
));
58 cl_git_pass(git_repository_config(&cfg
, g_repo
));
60 git_config_get_string(&s
, cfg
, "submodule." SM_LIBGIT2B
".url"));
61 cl_assert_equal_s(s
, SM_LIBGIT2_URL
);
65 static int delete_one_config(const git_config_entry
*entry
, void *payload
)
67 git_config
*cfg
= payload
;
68 return git_config_delete_entry(cfg
, entry
->name
);
71 static int init_one_submodule(
72 git_submodule
*sm
, const char *name
, void *payload
)
76 return git_submodule_init(sm
, false);
79 void test_submodule_modify__init(void)
84 /* erase submodule data from .git/config */
85 cl_git_pass(git_repository_config(&cfg
, g_repo
));
87 git_config_foreach_match(cfg
, "submodule\\..*", delete_one_config
, cfg
));
90 /* confirm no submodule data in config */
91 cl_git_pass(git_repository_config(&cfg
, g_repo
));
92 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_unchanged.url"));
93 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_changed_head.url"));
94 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_added_and_uncommited.url"));
97 /* call init and see that settings are copied */
98 cl_git_pass(git_submodule_foreach(g_repo
, init_one_submodule
, NULL
));
100 git_submodule_reload_all(g_repo
, 1);
102 /* confirm submodule data in config */
103 cl_git_pass(git_repository_config(&cfg
, g_repo
));
104 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_unchanged.url"));
105 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
106 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_changed_head.url"));
107 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
108 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_added_and_uncommited.url"));
109 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
110 git_config_free(cfg
);
113 static int sync_one_submodule(
114 git_submodule
*sm
, const char *name
, void *payload
)
118 return git_submodule_sync(sm
);
121 void test_submodule_modify__sync(void)
123 git_submodule
*sm1
, *sm2
, *sm3
;
127 #define SM1 "sm_unchanged"
128 #define SM2 "sm_changed_head"
129 #define SM3 "sm_added_and_uncommited"
131 /* look up some submodules */
132 cl_git_pass(git_submodule_lookup(&sm1
, g_repo
, SM1
));
133 cl_git_pass(git_submodule_lookup(&sm2
, g_repo
, SM2
));
134 cl_git_pass(git_submodule_lookup(&sm3
, g_repo
, SM3
));
136 /* At this point, the .git/config URLs for the submodules have
137 * not be rewritten with the absolute paths (although the
138 * .gitmodules have. Let's confirm that they DO NOT match
139 * yet, then we can do a sync to make them match...
142 /* check submodule info does not match before sync */
143 cl_git_pass(git_repository_config(&cfg
, g_repo
));
144 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM1
".url"));
145 cl_assert(strcmp(git_submodule_url(sm1
), str
) != 0);
146 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM2
".url"));
147 cl_assert(strcmp(git_submodule_url(sm2
), str
) != 0);
148 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM3
".url"));
149 cl_assert(strcmp(git_submodule_url(sm3
), str
) != 0);
150 git_config_free(cfg
);
152 /* sync all the submodules */
153 cl_git_pass(git_submodule_foreach(g_repo
, sync_one_submodule
, NULL
));
155 /* check that submodule config is updated */
156 cl_git_pass(git_repository_config(&cfg
, g_repo
));
157 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM1
".url"));
158 cl_assert_equal_s(git_submodule_url(sm1
), str
);
159 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM2
".url"));
160 cl_assert_equal_s(git_submodule_url(sm2
), str
);
161 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM3
".url"));
162 cl_assert_equal_s(git_submodule_url(sm3
), str
);
163 git_config_free(cfg
);
165 git_submodule_free(sm1
);
166 git_submodule_free(sm2
);
167 git_submodule_free(sm3
);
170 void test_submodule_modify__edit_and_save(void)
172 git_submodule
*sm1
, *sm2
;
174 git_submodule_ignore_t old_ignore
;
175 git_submodule_update_t old_update
;
177 git_submodule_recurse_t old_fetchrecurse
;
179 cl_git_pass(git_submodule_lookup(&sm1
, g_repo
, "sm_changed_head"));
181 old_url
= git__strdup(git_submodule_url(sm1
));
183 /* modify properties of submodule */
184 cl_git_pass(git_submodule_set_url(sm1
, SM_LIBGIT2_URL
));
185 old_ignore
= git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_UNTRACKED
);
186 old_update
= git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_REBASE
);
187 old_fetchrecurse
= git_submodule_set_fetch_recurse_submodules(
188 sm1
, GIT_SUBMODULE_RECURSE_YES
);
190 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm1
));
192 GIT_SUBMODULE_IGNORE_UNTRACKED
, git_submodule_ignore(sm1
));
194 GIT_SUBMODULE_UPDATE_REBASE
, git_submodule_update(sm1
));
196 GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
198 /* revert without saving (and confirm setters return old value) */
199 cl_git_pass(git_submodule_set_url(sm1
, old_url
));
201 GIT_SUBMODULE_IGNORE_UNTRACKED
,
202 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_RESET
));
204 GIT_SUBMODULE_UPDATE_REBASE
,
205 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_RESET
));
207 GIT_SUBMODULE_RECURSE_YES
, git_submodule_set_fetch_recurse_submodules(
208 sm1
, GIT_SUBMODULE_RECURSE_RESET
));
210 /* check that revert was successful */
211 cl_assert_equal_s(old_url
, git_submodule_url(sm1
));
212 cl_assert_equal_i((int)old_ignore
, (int)git_submodule_ignore(sm1
));
213 cl_assert_equal_i((int)old_update
, (int)git_submodule_update(sm1
));
215 old_fetchrecurse
, git_submodule_fetch_recurse_submodules(sm1
));
217 /* modify properties of submodule (again) */
218 cl_git_pass(git_submodule_set_url(sm1
, SM_LIBGIT2_URL
));
219 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_UNTRACKED
);
220 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_REBASE
);
221 git_submodule_set_fetch_recurse_submodules(sm1
, GIT_SUBMODULE_RECURSE_YES
);
224 cl_git_pass(git_submodule_save(sm1
));
226 /* attempt to "revert" values */
227 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_RESET
);
228 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_RESET
);
230 /* but ignore and update should NOT revert because the RESET
231 * should now be the newly saved value...
234 (int)GIT_SUBMODULE_IGNORE_UNTRACKED
, (int)git_submodule_ignore(sm1
));
236 (int)GIT_SUBMODULE_UPDATE_REBASE
, (int)git_submodule_update(sm1
));
237 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
239 /* call reload and check that the new values are loaded */
240 cl_git_pass(git_submodule_reload(sm1
, 0));
242 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm1
));
244 (int)GIT_SUBMODULE_IGNORE_UNTRACKED
, (int)git_submodule_ignore(sm1
));
246 (int)GIT_SUBMODULE_UPDATE_REBASE
, (int)git_submodule_update(sm1
));
247 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
249 /* open a second copy of the repo and compare submodule */
250 cl_git_pass(git_repository_open(&r2
, "submod2"));
251 cl_git_pass(git_submodule_lookup(&sm2
, r2
, "sm_changed_head"));
253 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm2
));
255 GIT_SUBMODULE_IGNORE_UNTRACKED
, git_submodule_ignore(sm2
));
257 GIT_SUBMODULE_UPDATE_REBASE
, git_submodule_update(sm2
));
259 GIT_SUBMODULE_RECURSE_NO
, git_submodule_fetch_recurse_submodules(sm2
));
261 /* set fetchRecurseSubmodules on-demand */
262 cl_git_pass(git_submodule_reload(sm1
, 0));
263 git_submodule_set_fetch_recurse_submodules(sm1
, GIT_SUBMODULE_RECURSE_ONDEMAND
);
265 GIT_SUBMODULE_RECURSE_ONDEMAND
, git_submodule_fetch_recurse_submodules(sm1
));
267 cl_git_pass(git_submodule_save(sm1
));
268 cl_git_pass(git_submodule_reload(sm1
, 0));
270 GIT_SUBMODULE_RECURSE_ONDEMAND
, git_submodule_fetch_recurse_submodules(sm1
));
272 git_submodule_free(sm1
);
273 git_submodule_free(sm2
);
274 git_repository_free(r2
);