]> git.proxmox.com Git - libgit2.git/blob - tests/submodule/modify.c
Merge pull request #3010 from ethomson/checkout_invalid_path_err
[libgit2.git] / tests / submodule / modify.c
1 #include "clar_libgit2.h"
2 #include "posix.h"
3 #include "path.h"
4 #include "submodule_helpers.h"
5 #include "config/config_helpers.h"
6
7 static git_repository *g_repo = NULL;
8
9 #define SM_LIBGIT2_URL "https://github.com/libgit2/libgit2.git"
10 #define SM_LIBGIT2 "sm_libgit2"
11
12 void test_submodule_modify__initialize(void)
13 {
14 g_repo = setup_fixture_submod2();
15 }
16
17 static int delete_one_config(const git_config_entry *entry, void *payload)
18 {
19 git_config *cfg = payload;
20 return git_config_delete_entry(cfg, entry->name);
21 }
22
23 static int init_one_submodule(
24 git_submodule *sm, const char *name, void *payload)
25 {
26 GIT_UNUSED(name);
27 GIT_UNUSED(payload);
28 return git_submodule_init(sm, false);
29 }
30
31 void test_submodule_modify__init(void)
32 {
33 git_config *cfg;
34 const char *str;
35
36 /* erase submodule data from .git/config */
37 cl_git_pass(git_repository_config(&cfg, g_repo));
38 cl_git_pass(
39 git_config_foreach_match(cfg, "submodule\\..*", delete_one_config, cfg));
40 git_config_free(cfg);
41
42 /* confirm no submodule data in config */
43 cl_git_pass(git_repository_config(&cfg, g_repo));
44 cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
45 cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
46 cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
47 git_config_free(cfg);
48
49 /* call init and see that settings are copied */
50 cl_git_pass(git_submodule_foreach(g_repo, init_one_submodule, NULL));
51
52 git_submodule_reload_all(g_repo, 1);
53
54 /* confirm submodule data in config */
55 cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
56 cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
57 cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
58 cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
59 cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
60 cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
61 cl_assert(git__suffixcmp(str, "/submod2_target") == 0);
62 git_config_free(cfg);
63 }
64
65 static int sync_one_submodule(
66 git_submodule *sm, const char *name, void *payload)
67 {
68 GIT_UNUSED(name);
69 GIT_UNUSED(payload);
70 return git_submodule_sync(sm);
71 }
72
73 static void assert_submodule_url_is_synced(
74 git_submodule *sm, const char *parent_key, const char *child_key)
75 {
76 git_repository *smrepo;
77
78 assert_config_entry_value(g_repo, parent_key, git_submodule_url(sm));
79
80 cl_git_pass(git_submodule_open(&smrepo, sm));
81 assert_config_entry_value(smrepo, child_key, git_submodule_url(sm));
82 git_repository_free(smrepo);
83 }
84
85 void test_submodule_modify__sync(void)
86 {
87 git_submodule *sm1, *sm2, *sm3;
88 git_config *cfg;
89 const char *str;
90
91 #define SM1 "sm_unchanged"
92 #define SM2 "sm_changed_head"
93 #define SM3 "sm_added_and_uncommited"
94
95 /* look up some submodules */
96 cl_git_pass(git_submodule_lookup(&sm1, g_repo, SM1));
97 cl_git_pass(git_submodule_lookup(&sm2, g_repo, SM2));
98 cl_git_pass(git_submodule_lookup(&sm3, g_repo, SM3));
99
100 /* At this point, the .git/config URLs for the submodules have
101 * not be rewritten with the absolute paths (although the
102 * .gitmodules have. Let's confirm that they DO NOT match
103 * yet, then we can do a sync to make them match...
104 */
105
106 /* check submodule info does not match before sync */
107 cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
108 cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM1".url"));
109 cl_assert(strcmp(git_submodule_url(sm1), str) != 0);
110 cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM2".url"));
111 cl_assert(strcmp(git_submodule_url(sm2), str) != 0);
112 cl_git_pass(git_config_get_string(&str, cfg, "submodule."SM3".url"));
113 cl_assert(strcmp(git_submodule_url(sm3), str) != 0);
114 git_config_free(cfg);
115
116 /* sync all the submodules */
117 cl_git_pass(git_submodule_foreach(g_repo, sync_one_submodule, NULL));
118
119 /* check that submodule config is updated */
120 assert_submodule_url_is_synced(
121 sm1, "submodule."SM1".url", "remote.origin.url");
122 assert_submodule_url_is_synced(
123 sm2, "submodule."SM2".url", "remote.origin.url");
124 assert_submodule_url_is_synced(
125 sm3, "submodule."SM3".url", "remote.origin.url");
126
127 git_submodule_free(sm1);
128 git_submodule_free(sm2);
129 git_submodule_free(sm3);
130 }
131
132 void test_submodule_modify__edit_and_save(void)
133 {
134 git_submodule *sm1, *sm2;
135 char *old_url;
136 git_submodule_ignore_t old_ignore;
137 git_submodule_update_t old_update;
138 git_repository *r2;
139 git_submodule_recurse_t old_fetchrecurse;
140
141 cl_git_pass(git_submodule_lookup(&sm1, g_repo, "sm_changed_head"));
142
143 old_url = git__strdup(git_submodule_url(sm1));
144
145 /* modify properties of submodule */
146 cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
147 old_ignore = git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
148 old_update = git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
149 old_fetchrecurse = git_submodule_set_fetch_recurse_submodules(
150 sm1, GIT_SUBMODULE_RECURSE_YES);
151
152 cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
153 cl_assert_equal_i(
154 GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm1));
155 cl_assert_equal_i(
156 GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm1));
157 cl_assert_equal_i(
158 GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
159
160 /* revert without saving (and confirm setters return old value) */
161 cl_git_pass(git_submodule_set_url(sm1, old_url));
162 cl_assert_equal_i(
163 GIT_SUBMODULE_IGNORE_UNTRACKED,
164 git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET));
165 cl_assert_equal_i(
166 GIT_SUBMODULE_UPDATE_REBASE,
167 git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET));
168 cl_assert_equal_i(
169 GIT_SUBMODULE_RECURSE_YES, git_submodule_set_fetch_recurse_submodules(
170 sm1, GIT_SUBMODULE_RECURSE_RESET));
171
172 /* check that revert was successful */
173 cl_assert_equal_s(old_url, git_submodule_url(sm1));
174 cl_assert_equal_i((int)old_ignore, (int)git_submodule_ignore(sm1));
175 cl_assert_equal_i((int)old_update, (int)git_submodule_update_strategy(sm1));
176 cl_assert_equal_i(
177 old_fetchrecurse, git_submodule_fetch_recurse_submodules(sm1));
178
179 /* modify properties of submodule (again) */
180 cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
181 git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
182 git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
183 git_submodule_set_fetch_recurse_submodules(sm1, GIT_SUBMODULE_RECURSE_YES);
184
185 /* call save */
186 cl_git_pass(git_submodule_save(sm1));
187
188 /* attempt to "revert" values */
189 git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET);
190 git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET);
191
192 /* but ignore and update should NOT revert because the RESET
193 * should now be the newly saved value...
194 */
195 cl_assert_equal_i(
196 (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
197 cl_assert_equal_i(
198 (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
199 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
200
201 /* call reload and check that the new values are loaded */
202 cl_git_pass(git_submodule_reload(sm1, 0));
203
204 cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
205 cl_assert_equal_i(
206 (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
207 cl_assert_equal_i(
208 (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
209 cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
210
211 /* open a second copy of the repo and compare submodule */
212 cl_git_pass(git_repository_open(&r2, "submod2"));
213 cl_git_pass(git_submodule_lookup(&sm2, r2, "sm_changed_head"));
214
215 cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm2));
216 cl_assert_equal_i(
217 GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm2));
218 cl_assert_equal_i(
219 GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm2));
220 cl_assert_equal_i(
221 GIT_SUBMODULE_RECURSE_NO, git_submodule_fetch_recurse_submodules(sm2));
222
223 /* set fetchRecurseSubmodules on-demand */
224 cl_git_pass(git_submodule_reload(sm1, 0));
225 git_submodule_set_fetch_recurse_submodules(sm1, GIT_SUBMODULE_RECURSE_ONDEMAND);
226 cl_assert_equal_i(
227 GIT_SUBMODULE_RECURSE_ONDEMAND, git_submodule_fetch_recurse_submodules(sm1));
228 /* call save */
229 cl_git_pass(git_submodule_save(sm1));
230 cl_git_pass(git_submodule_reload(sm1, 0));
231 cl_assert_equal_i(
232 GIT_SUBMODULE_RECURSE_ONDEMAND, git_submodule_fetch_recurse_submodules(sm1));
233
234 git_submodule_free(sm1);
235 git_submodule_free(sm2);
236 git_repository_free(r2);
237 git__free(old_url);
238 }