1 #include "clar_libgit2.h"
4 #include "submodule_helpers.h"
5 #include "config/config_helpers.h"
7 static git_repository
*g_repo
= NULL
;
9 #define SM_LIBGIT2_URL "https://github.com/libgit2/libgit2.git"
10 #define SM_LIBGIT2_BRANCH "github-branch"
11 #define SM_LIBGIT2 "sm_libgit2"
13 void test_submodule_modify__initialize(void)
15 g_repo
= setup_fixture_submod2();
18 static int delete_one_config(const git_config_entry
*entry
, void *payload
)
20 git_config
*cfg
= payload
;
21 return git_config_delete_entry(cfg
, entry
->name
);
24 static int init_one_submodule(
25 git_submodule
*sm
, const char *name
, void *payload
)
29 return git_submodule_init(sm
, false);
32 void test_submodule_modify__init(void)
37 /* erase submodule data from .git/config */
38 cl_git_pass(git_repository_config(&cfg
, g_repo
));
40 git_config_foreach_match(cfg
, "submodule\\..*", delete_one_config
, cfg
));
43 /* confirm no submodule data in config */
44 cl_git_pass(git_repository_config(&cfg
, g_repo
));
45 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_unchanged.url"));
46 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_changed_head.url"));
47 cl_git_fail(git_config_get_string(&str
, cfg
, "submodule.sm_added_and_uncommited.url"));
50 /* call init and see that settings are copied */
51 cl_git_pass(git_submodule_foreach(g_repo
, init_one_submodule
, NULL
));
53 git_submodule_reload_all(g_repo
, 1);
55 /* confirm submodule data in config */
56 cl_git_pass(git_repository_config_snapshot(&cfg
, g_repo
));
57 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_unchanged.url"));
58 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
59 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_changed_head.url"));
60 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
61 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule.sm_added_and_uncommited.url"));
62 cl_assert(git__suffixcmp(str
, "/submod2_target") == 0);
66 static int sync_one_submodule(
67 git_submodule
*sm
, const char *name
, void *payload
)
71 return git_submodule_sync(sm
);
74 static void assert_submodule_url_is_synced(
75 git_submodule
*sm
, const char *parent_key
, const char *child_key
)
77 git_repository
*smrepo
;
79 assert_config_entry_value(g_repo
, parent_key
, git_submodule_url(sm
));
81 cl_git_pass(git_submodule_open(&smrepo
, sm
));
82 assert_config_entry_value(smrepo
, child_key
, git_submodule_url(sm
));
83 git_repository_free(smrepo
);
86 void test_submodule_modify__sync(void)
88 git_submodule
*sm1
, *sm2
, *sm3
;
92 #define SM1 "sm_unchanged"
93 #define SM2 "sm_changed_head"
94 #define SM3 "sm_added_and_uncommited"
96 /* look up some submodules */
97 cl_git_pass(git_submodule_lookup(&sm1
, g_repo
, SM1
));
98 cl_git_pass(git_submodule_lookup(&sm2
, g_repo
, SM2
));
99 cl_git_pass(git_submodule_lookup(&sm3
, g_repo
, SM3
));
101 /* At this point, the .git/config URLs for the submodules have
102 * not be rewritten with the absolute paths (although the
103 * .gitmodules have. Let's confirm that they DO NOT match
104 * yet, then we can do a sync to make them match...
107 /* check submodule info does not match before sync */
108 cl_git_pass(git_repository_config_snapshot(&cfg
, g_repo
));
109 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM1
".url"));
110 cl_assert(strcmp(git_submodule_url(sm1
), str
) != 0);
111 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM2
".url"));
112 cl_assert(strcmp(git_submodule_url(sm2
), str
) != 0);
113 cl_git_pass(git_config_get_string(&str
, cfg
, "submodule."SM3
".url"));
114 cl_assert(strcmp(git_submodule_url(sm3
), str
) != 0);
115 git_config_free(cfg
);
117 /* sync all the submodules */
118 cl_git_pass(git_submodule_foreach(g_repo
, sync_one_submodule
, NULL
));
120 /* check that submodule config is updated */
121 assert_submodule_url_is_synced(
122 sm1
, "submodule."SM1
".url", "remote.origin.url");
123 assert_submodule_url_is_synced(
124 sm2
, "submodule."SM2
".url", "remote.origin.url");
125 assert_submodule_url_is_synced(
126 sm3
, "submodule."SM3
".url", "remote.origin.url");
128 git_submodule_free(sm1
);
129 git_submodule_free(sm2
);
130 git_submodule_free(sm3
);
133 void test_submodule_modify__edit_and_save(void)
135 git_submodule
*sm1
, *sm2
;
136 char *old_url
, *old_branch
;
137 git_submodule_ignore_t old_ignore
;
138 git_submodule_update_t old_update
;
140 git_submodule_recurse_t old_fetchrecurse
;
142 cl_git_pass(git_submodule_lookup(&sm1
, g_repo
, "sm_changed_head"));
144 old_url
= git__strdup(git_submodule_url(sm1
));
147 /* modify properties of submodule */
148 cl_git_pass(git_submodule_set_url(sm1
, SM_LIBGIT2_URL
));
149 cl_git_pass(git_submodule_set_branch(sm1
, SM_LIBGIT2_BRANCH
));
150 old_ignore
= git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_UNTRACKED
);
151 old_update
= git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_REBASE
);
152 old_fetchrecurse
= git_submodule_set_fetch_recurse_submodules(
153 sm1
, GIT_SUBMODULE_RECURSE_YES
);
155 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm1
));
156 cl_assert_equal_s(SM_LIBGIT2_BRANCH
, git_submodule_branch(sm1
));
158 GIT_SUBMODULE_IGNORE_UNTRACKED
, git_submodule_ignore(sm1
));
160 GIT_SUBMODULE_UPDATE_REBASE
, git_submodule_update_strategy(sm1
));
162 GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
164 /* revert without saving (and confirm setters return old value) */
165 cl_git_pass(git_submodule_set_url(sm1
, old_url
));
166 cl_git_pass(git_submodule_set_branch(sm1
, old_branch
));
168 GIT_SUBMODULE_IGNORE_UNTRACKED
,
169 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_RESET
));
171 GIT_SUBMODULE_UPDATE_REBASE
,
172 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_RESET
));
174 GIT_SUBMODULE_RECURSE_YES
, git_submodule_set_fetch_recurse_submodules(
175 sm1
, GIT_SUBMODULE_RECURSE_RESET
));
177 /* check that revert was successful */
178 cl_assert_equal_s(old_url
, git_submodule_url(sm1
));
179 cl_assert_equal_s(old_branch
, git_submodule_branch(sm1
));
180 cl_assert_equal_i((int)old_ignore
, (int)git_submodule_ignore(sm1
));
181 cl_assert_equal_i((int)old_update
, (int)git_submodule_update_strategy(sm1
));
183 old_fetchrecurse
, git_submodule_fetch_recurse_submodules(sm1
));
185 /* modify properties of submodule (again) */
186 cl_git_pass(git_submodule_set_url(sm1
, SM_LIBGIT2_URL
));
187 cl_git_pass(git_submodule_set_branch(sm1
, SM_LIBGIT2_BRANCH
));
188 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_UNTRACKED
);
189 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_REBASE
);
190 git_submodule_set_fetch_recurse_submodules(sm1
, GIT_SUBMODULE_RECURSE_YES
);
193 cl_git_pass(git_submodule_save(sm1
));
195 /* attempt to "revert" values */
196 git_submodule_set_ignore(sm1
, GIT_SUBMODULE_IGNORE_RESET
);
197 git_submodule_set_update(sm1
, GIT_SUBMODULE_UPDATE_RESET
);
199 /* but ignore and update should NOT revert because the RESET
200 * should now be the newly saved value...
203 (int)GIT_SUBMODULE_IGNORE_UNTRACKED
, (int)git_submodule_ignore(sm1
));
205 (int)GIT_SUBMODULE_UPDATE_REBASE
, (int)git_submodule_update_strategy(sm1
));
206 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
208 /* call reload and check that the new values are loaded */
209 cl_git_pass(git_submodule_reload(sm1
, 0));
211 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm1
));
212 cl_assert_equal_s(SM_LIBGIT2_BRANCH
, git_submodule_branch(sm1
));
214 (int)GIT_SUBMODULE_IGNORE_UNTRACKED
, (int)git_submodule_ignore(sm1
));
216 (int)GIT_SUBMODULE_UPDATE_REBASE
, (int)git_submodule_update_strategy(sm1
));
217 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES
, git_submodule_fetch_recurse_submodules(sm1
));
219 /* unset branch again and verify that the property is deleted in config */
220 cl_git_pass(git_submodule_set_branch(sm1
, NULL
));
221 cl_git_pass(git_submodule_save(sm1
));
222 cl_git_pass(git_submodule_reload(sm1
, 0));
223 cl_assert_equal_s(NULL
, git_submodule_branch(sm1
));
225 /* open a second copy of the repo and compare submodule */
226 cl_git_pass(git_repository_open(&r2
, "submod2"));
227 cl_git_pass(git_submodule_lookup(&sm2
, r2
, "sm_changed_head"));
229 cl_assert_equal_s(SM_LIBGIT2_URL
, git_submodule_url(sm2
));
231 GIT_SUBMODULE_IGNORE_UNTRACKED
, git_submodule_ignore(sm2
));
233 GIT_SUBMODULE_UPDATE_REBASE
, git_submodule_update_strategy(sm2
));
235 GIT_SUBMODULE_RECURSE_NO
, git_submodule_fetch_recurse_submodules(sm2
));
237 /* set fetchRecurseSubmodules on-demand */
238 cl_git_pass(git_submodule_reload(sm1
, 0));
239 git_submodule_set_fetch_recurse_submodules(sm1
, GIT_SUBMODULE_RECURSE_ONDEMAND
);
241 GIT_SUBMODULE_RECURSE_ONDEMAND
, git_submodule_fetch_recurse_submodules(sm1
));
243 cl_git_pass(git_submodule_save(sm1
));
244 cl_git_pass(git_submodule_reload(sm1
, 0));
246 GIT_SUBMODULE_RECURSE_ONDEMAND
, git_submodule_fetch_recurse_submodules(sm1
));
248 git_submodule_free(sm1
);
249 git_submodule_free(sm2
);
250 git_repository_free(r2
);
254 void test_submodule_modify__save_last(void)
258 cl_git_pass(git_submodule_lookup(&sm
, g_repo
, "sm_gitmodules_only"));
259 cl_git_pass(git_submodule_save(sm
));
260 git_submodule_free(sm
);