]>
Commit | Line | Data |
---|---|---|
613d5eb9 | 1 | #include "clar_libgit2.h" |
613d5eb9 PK |
2 | #include "posix.h" |
3 | #include "vector.h" | |
4 | #include "../submodule/submodule_helpers.h" | |
5 | #include "push_util.h" | |
1d645aab JM |
6 | #include "refspec.h" |
7 | #include "remote.h" | |
613d5eb9 | 8 | |
613d5eb9 PK |
9 | static git_repository *_repo; |
10 | ||
e069c621 | 11 | static char *_remote_url = NULL; |
84efffc3 | 12 | |
e069c621 ET |
13 | static char *_remote_user = NULL; |
14 | static char *_remote_pass = NULL; | |
5be622fb | 15 | |
e069c621 ET |
16 | static char *_remote_ssh_key = NULL; |
17 | static char *_remote_ssh_pubkey = NULL; | |
18 | static char *_remote_ssh_passphrase = NULL; | |
613d5eb9 | 19 | |
e069c621 | 20 | static char *_remote_default = NULL; |
22a2d3d5 | 21 | static char *_remote_expectcontinue = NULL; |
84efffc3 | 22 | |
22a2d3d5 | 23 | static int cred_acquire_cb(git_credential **, const char *, const char *, unsigned int, void *); |
e3c131c5 | 24 | |
613d5eb9 PK |
25 | static git_remote *_remote; |
26 | static record_callbacks_data _record_cbs_data = {{ 0 }}; | |
27 | static git_remote_callbacks _record_cbs = RECORD_CALLBACKS_INIT(&_record_cbs_data); | |
28 | ||
29 | static git_oid _oid_b6; | |
30 | static git_oid _oid_b5; | |
31 | static git_oid _oid_b4; | |
32 | static git_oid _oid_b3; | |
33 | static git_oid _oid_b2; | |
34 | static git_oid _oid_b1; | |
35 | ||
abeefbbe MS |
36 | static git_oid _tag_commit; |
37 | static git_oid _tag_tree; | |
38 | static git_oid _tag_blob; | |
39 | static git_oid _tag_lightweight; | |
1c13b0bf | 40 | static git_oid _tag_tag; |
abeefbbe | 41 | |
7602cb7c | 42 | static int cred_acquire_cb( |
22a2d3d5 | 43 | git_credential **cred, |
2648dc1a ET |
44 | const char *url, |
45 | const char *user_from_url, | |
46 | unsigned int allowed_types, | |
47 | void *payload) | |
613d5eb9 PK |
48 | { |
49 | GIT_UNUSED(url); | |
7602cb7c | 50 | GIT_UNUSED(user_from_url); |
2648dc1a | 51 | GIT_UNUSED(payload); |
613d5eb9 | 52 | |
22a2d3d5 | 53 | if (GIT_CREDENTIAL_USERNAME & allowed_types) { |
e26b08d3 CMN |
54 | if (!_remote_user) { |
55 | printf("GITTEST_REMOTE_USER must be set\n"); | |
56 | return -1; | |
57 | } | |
58 | ||
22a2d3d5 | 59 | return git_credential_username_new(cred, _remote_user); |
e26b08d3 CMN |
60 | } |
61 | ||
22a2d3d5 | 62 | if (GIT_CREDENTIAL_DEFAULT & allowed_types) { |
84efffc3 ET |
63 | if (!_remote_default) { |
64 | printf("GITTEST_REMOTE_DEFAULT must be set to use NTLM/Negotiate credentials\n"); | |
65 | return -1; | |
66 | } | |
67 | ||
22a2d3d5 | 68 | return git_credential_default_new(cred); |
84efffc3 ET |
69 | } |
70 | ||
22a2d3d5 | 71 | if (GIT_CREDENTIAL_SSH_KEY & allowed_types) { |
2648dc1a ET |
72 | if (!_remote_user || !_remote_ssh_pubkey || !_remote_ssh_key || !_remote_ssh_passphrase) { |
73 | printf("GITTEST_REMOTE_USER, GITTEST_REMOTE_SSH_PUBKEY, GITTEST_REMOTE_SSH_KEY and GITTEST_REMOTE_SSH_PASSPHRASE must be set\n"); | |
74 | return -1; | |
75 | } | |
84efffc3 | 76 | |
22a2d3d5 | 77 | return git_credential_ssh_key_new(cred, _remote_user, _remote_ssh_pubkey, _remote_ssh_key, _remote_ssh_passphrase); |
2648dc1a | 78 | } |
5be622fb | 79 | |
22a2d3d5 | 80 | if (GIT_CREDENTIAL_USERPASS_PLAINTEXT & allowed_types) { |
2648dc1a ET |
81 | if (!_remote_user || !_remote_pass) { |
82 | printf("GITTEST_REMOTE_USER and GITTEST_REMOTE_PASS must be set\n"); | |
83 | return -1; | |
84 | } | |
613d5eb9 | 85 | |
22a2d3d5 | 86 | return git_credential_userpass_plaintext_new(cred, _remote_user, _remote_pass); |
2648dc1a ET |
87 | } |
88 | ||
89 | return -1; | |
613d5eb9 PK |
90 | } |
91 | ||
613d5eb9 PK |
92 | /** |
93 | * git_push_status_foreach callback that records status entries. | |
613d5eb9 | 94 | */ |
6eb9e39c | 95 | static int record_push_status_cb(const char *ref, const char *msg, void *payload) |
613d5eb9 | 96 | { |
6eb9e39c | 97 | record_callbacks_data *data = (record_callbacks_data *) payload; |
613d5eb9 PK |
98 | push_status *s; |
99 | ||
6eb9e39c CMN |
100 | cl_assert(s = git__calloc(1, sizeof(*s))); |
101 | if (ref) | |
102 | cl_assert(s->ref = git__strdup(ref)); | |
9d41984c | 103 | s->success = (msg == NULL); |
6eb9e39c CMN |
104 | if (msg) |
105 | cl_assert(s->msg = git__strdup(msg)); | |
613d5eb9 | 106 | |
6eb9e39c | 107 | git_vector_insert(&data->statuses, s); |
613d5eb9 PK |
108 | |
109 | return 0; | |
110 | } | |
111 | ||
6eb9e39c | 112 | static void do_verify_push_status(record_callbacks_data *data, const push_status expected[], const size_t expected_len) |
613d5eb9 | 113 | { |
6eb9e39c | 114 | git_vector *actual = &data->statuses; |
613d5eb9 PK |
115 | push_status *iter; |
116 | bool failed = false; | |
117 | size_t i; | |
118 | ||
6eb9e39c | 119 | if (expected_len != actual->length) |
613d5eb9 PK |
120 | failed = true; |
121 | else | |
6eb9e39c | 122 | git_vector_foreach(actual, i, iter) |
613d5eb9 | 123 | if (strcmp(expected[i].ref, iter->ref) || |
9d41984c ET |
124 | (expected[i].success != iter->success) || |
125 | (expected[i].msg && (!iter->msg || strcmp(expected[i].msg, iter->msg)))) { | |
613d5eb9 PK |
126 | failed = true; |
127 | break; | |
128 | } | |
129 | ||
130 | if (failed) { | |
e579e0f7 | 131 | git_str msg = GIT_STR_INIT; |
613d5eb9 | 132 | |
e579e0f7 | 133 | git_str_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n"); |
613d5eb9 PK |
134 | |
135 | for(i = 0; i < expected_len; i++) { | |
e579e0f7 | 136 | git_str_printf(&msg, "%s: %s\n", |
613d5eb9 | 137 | expected[i].ref, |
9d41984c | 138 | expected[i].success ? "success" : "failed"); |
613d5eb9 PK |
139 | } |
140 | ||
e579e0f7 | 141 | git_str_puts(&msg, "\nACTUAL:\n"); |
613d5eb9 | 142 | |
6eb9e39c | 143 | git_vector_foreach(actual, i, iter) { |
9d41984c | 144 | if (iter->success) |
e579e0f7 | 145 | git_str_printf(&msg, "%s: success\n", iter->ref); |
9d41984c | 146 | else |
e579e0f7 | 147 | git_str_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg); |
9d41984c | 148 | } |
613d5eb9 | 149 | |
e579e0f7 | 150 | cl_fail(git_str_cstr(&msg)); |
613d5eb9 | 151 | |
e579e0f7 | 152 | git_str_dispose(&msg); |
613d5eb9 PK |
153 | } |
154 | ||
6c7cee42 RD |
155 | git_vector_foreach(actual, i, iter) { |
156 | push_status *s = (push_status *)iter; | |
157 | git__free(s->ref); | |
158 | git__free(s->msg); | |
159 | git__free(s); | |
160 | } | |
613d5eb9 | 161 | |
6eb9e39c | 162 | git_vector_free(actual); |
613d5eb9 PK |
163 | } |
164 | ||
165 | /** | |
166 | * Verifies that after git_push_finish(), refs on a remote have the expected | |
167 | * names, oids, and order. | |
156cfec0 | 168 | * |
613d5eb9 PK |
169 | * @param remote remote to verify |
170 | * @param expected_refs expected remote refs after push | |
171 | * @param expected_refs_len length of expected_refs | |
172 | */ | |
173 | static void verify_refs(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len) | |
174 | { | |
359dce72 CMN |
175 | const git_remote_head **actual_refs; |
176 | size_t actual_refs_len; | |
613d5eb9 | 177 | |
359dce72 CMN |
178 | git_remote_ls(&actual_refs, &actual_refs_len, remote); |
179 | verify_remote_refs(actual_refs, actual_refs_len, expected_refs, expected_refs_len); | |
613d5eb9 PK |
180 | } |
181 | ||
1d645aab JM |
182 | /** |
183 | * Verifies that after git_push_update_tips(), remote tracking branches have the expected | |
184 | * names and oids. | |
185 | * | |
186 | * @param remote remote to verify | |
187 | * @param expected_refs expected remote refs after push | |
188 | * @param expected_refs_len length of expected_refs | |
189 | */ | |
190 | static void verify_tracking_branches(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len) | |
191 | { | |
4330ab26 | 192 | git_refspec *fetch_spec; |
1d645aab | 193 | size_t i, j; |
e579e0f7 | 194 | git_str msg = GIT_STR_INIT; |
1d645aab | 195 | git_buf ref_name = GIT_BUF_INIT; |
1d645aab | 196 | git_vector actual_refs = GIT_VECTOR_INIT; |
8ec889a4 | 197 | git_branch_iterator *iter; |
1d645aab JM |
198 | char *actual_ref; |
199 | git_oid oid; | |
8ec889a4 | 200 | int failed = 0, error; |
a667ca82 | 201 | git_branch_t branch_type; |
8ec889a4 | 202 | git_reference *ref; |
1d645aab | 203 | |
fe794b2e | 204 | /* Get current remote-tracking branches */ |
8ec889a4 CMN |
205 | cl_git_pass(git_branch_iterator_new(&iter, remote->repo, GIT_BRANCH_REMOTE)); |
206 | ||
207 | while ((error = git_branch_next(&ref, &branch_type, iter)) == 0) { | |
208 | cl_assert_equal_i(branch_type, GIT_BRANCH_REMOTE); | |
209 | ||
210 | cl_git_pass(git_vector_insert(&actual_refs, git__strdup(git_reference_name(ref)))); | |
f96e7e6c ET |
211 | |
212 | git_reference_free(ref); | |
8ec889a4 CMN |
213 | } |
214 | ||
215 | cl_assert_equal_i(error, GIT_ITEROVER); | |
11bd7a03 | 216 | git_branch_iterator_free(iter); |
1d645aab JM |
217 | |
218 | /* Loop through expected refs, make sure they exist */ | |
219 | for (i = 0; i < expected_refs_len; i++) { | |
220 | ||
fe794b2e | 221 | /* Convert remote reference name into remote-tracking branch name. |
1d645aab JM |
222 | * If the spec is not under refs/heads/, then skip. |
223 | */ | |
4330ab26 CMN |
224 | fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name); |
225 | if (!fetch_spec) | |
1d645aab JM |
226 | continue; |
227 | ||
bf522e08 | 228 | cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name)); |
1d645aab JM |
229 | |
230 | /* Find matching remote branch */ | |
231 | git_vector_foreach(&actual_refs, j, actual_ref) { | |
e579e0f7 | 232 | if (!strcmp(ref_name.ptr, actual_ref)) |
1d645aab JM |
233 | break; |
234 | } | |
235 | ||
236 | if (j == actual_refs.length) { | |
e579e0f7 | 237 | git_str_printf(&msg, "Did not find expected tracking branch '%s'.", ref_name.ptr); |
1d645aab JM |
238 | failed = 1; |
239 | goto failed; | |
240 | } | |
241 | ||
242 | /* Make sure tracking branch is at expected commit ID */ | |
8ec889a4 | 243 | cl_git_pass(git_reference_name_to_id(&oid, remote->repo, actual_ref)); |
1d645aab JM |
244 | |
245 | if (git_oid_cmp(expected_refs[i].oid, &oid) != 0) { | |
e579e0f7 | 246 | git_str_puts(&msg, "Tracking branch commit does not match expected ID."); |
1d645aab JM |
247 | failed = 1; |
248 | goto failed; | |
249 | } | |
250 | ||
2ff4469a | 251 | git__free(actual_ref); |
1d645aab JM |
252 | cl_git_pass(git_vector_remove(&actual_refs, j)); |
253 | } | |
254 | ||
255 | /* Make sure there are no extra branches */ | |
256 | if (actual_refs.length > 0) { | |
e579e0f7 | 257 | git_str_puts(&msg, "Unexpected remote tracking branches exist."); |
1d645aab JM |
258 | failed = 1; |
259 | goto failed; | |
260 | } | |
261 | ||
262 | failed: | |
f70cfd34 | 263 | if (failed) |
e579e0f7 | 264 | cl_fail(git_str_cstr(&msg)); |
1d645aab JM |
265 | |
266 | git_vector_foreach(&actual_refs, i, actual_ref) | |
267 | git__free(actual_ref); | |
268 | ||
269 | git_vector_free(&actual_refs); | |
e579e0f7 | 270 | git_str_dispose(&msg); |
ac3d33df | 271 | git_buf_dispose(&ref_name); |
f70cfd34 JG |
272 | } |
273 | ||
274 | static void verify_update_tips_callback(git_remote *remote, expected_ref expected_refs[], size_t expected_refs_len) | |
275 | { | |
276 | git_refspec *fetch_spec; | |
e579e0f7 | 277 | git_str msg = GIT_STR_INIT; |
f70cfd34 JG |
278 | git_buf ref_name = GIT_BUF_INIT; |
279 | updated_tip *tip = NULL; | |
280 | size_t i, j; | |
281 | int failed = 0; | |
282 | ||
283 | for (i = 0; i < expected_refs_len; ++i) { | |
284 | /* Convert remote reference name into tracking branch name. | |
285 | * If the spec is not under refs/heads/, then skip. | |
286 | */ | |
287 | fetch_spec = git_remote__matching_refspec(remote, expected_refs[i].name); | |
288 | if (!fetch_spec) | |
289 | continue; | |
290 | ||
291 | cl_git_pass(git_refspec_transform(&ref_name, fetch_spec, expected_refs[i].name)); | |
292 | ||
293 | /* Find matching update_tip entry */ | |
294 | git_vector_foreach(&_record_cbs_data.updated_tips, j, tip) { | |
e579e0f7 | 295 | if (!strcmp(ref_name.ptr, tip->name)) |
f70cfd34 JG |
296 | break; |
297 | } | |
298 | ||
299 | if (j == _record_cbs_data.updated_tips.length) { | |
e579e0f7 | 300 | git_str_printf(&msg, "Did not find expected updated tip entry for branch '%s'.", ref_name.ptr); |
f70cfd34 JG |
301 | failed = 1; |
302 | goto failed; | |
303 | } | |
304 | ||
1af5aecb | 305 | if (git_oid_cmp(expected_refs[i].oid, &tip->new_oid) != 0) { |
e579e0f7 | 306 | git_str_printf(&msg, "Updated tip ID does not match expected ID"); |
f70cfd34 JG |
307 | failed = 1; |
308 | goto failed; | |
309 | } | |
310 | } | |
311 | ||
312 | failed: | |
313 | if (failed) | |
e579e0f7 | 314 | cl_fail(git_str_cstr(&msg)); |
f70cfd34 | 315 | |
ac3d33df | 316 | git_buf_dispose(&ref_name); |
e579e0f7 | 317 | git_str_dispose(&msg); |
1d645aab JM |
318 | } |
319 | ||
6443eaf2 | 320 | void test_online_push__initialize(void) |
613d5eb9 PK |
321 | { |
322 | git_vector delete_specs = GIT_VECTOR_INIT; | |
ae297212 | 323 | const git_remote_head **heads; |
fe794b2e | 324 | size_t heads_len; |
0f69b41d CMN |
325 | git_push_options push_opts = GIT_PUSH_OPTIONS_INIT; |
326 | git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; | |
613d5eb9 PK |
327 | |
328 | _repo = cl_git_sandbox_init("push_src"); | |
329 | ||
659cf202 | 330 | cl_git_pass(git_repository_set_ident(_repo, "Random J. Hacker", "foo@example.com")); |
613d5eb9 PK |
331 | cl_fixture_sandbox("testrepo.git"); |
332 | cl_rename("push_src/submodule/.gitted", "push_src/submodule/.git"); | |
333 | ||
334 | rewrite_gitmodules(git_repository_workdir(_repo)); | |
335 | ||
336 | /* git log --format=oneline --decorate --graph | |
337 | * *-. 951bbbb90e2259a4c8950db78946784fb53fcbce (HEAD, b6) merge b3, b4, and b5 to b6 | |
338 | * |\ \ | |
339 | * | | * fa38b91f199934685819bea316186d8b008c52a2 (b5) added submodule named 'submodule' pointing to '../testrepo.git' | |
340 | * | * | 27b7ce66243eb1403862d05f958c002312df173d (b4) edited fold\b.txt | |
341 | * | |/ | |
342 | * * | d9b63a88223d8367516f50bd131a5f7349b7f3e4 (b3) edited a.txt | |
343 | * |/ | |
344 | * * a78705c3b2725f931d3ee05348d83cc26700f247 (b2, b1) added fold and fold/b.txt | |
345 | * * 5c0bb3d1b9449d1cc69d7519fd05166f01840915 added a.txt | |
346 | */ | |
347 | git_oid_fromstr(&_oid_b6, "951bbbb90e2259a4c8950db78946784fb53fcbce"); | |
348 | git_oid_fromstr(&_oid_b5, "fa38b91f199934685819bea316186d8b008c52a2"); | |
349 | git_oid_fromstr(&_oid_b4, "27b7ce66243eb1403862d05f958c002312df173d"); | |
350 | git_oid_fromstr(&_oid_b3, "d9b63a88223d8367516f50bd131a5f7349b7f3e4"); | |
351 | git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247"); | |
352 | git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247"); | |
353 | ||
abeefbbe MS |
354 | git_oid_fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac"); |
355 | git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e"); | |
356 | git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498"); | |
357 | git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce"); | |
1c13b0bf | 358 | git_oid_fromstr(&_tag_tag, "eea4f2705eeec2db3813f2430829afce99cd00b5"); |
abeefbbe | 359 | |
613d5eb9 | 360 | /* Remote URL environment variable must be set. User and password are optional. */ |
e069c621 | 361 | |
613d5eb9 PK |
362 | _remote_url = cl_getenv("GITTEST_REMOTE_URL"); |
363 | _remote_user = cl_getenv("GITTEST_REMOTE_USER"); | |
364 | _remote_pass = cl_getenv("GITTEST_REMOTE_PASS"); | |
5be622fb CMN |
365 | _remote_ssh_key = cl_getenv("GITTEST_REMOTE_SSH_KEY"); |
366 | _remote_ssh_pubkey = cl_getenv("GITTEST_REMOTE_SSH_PUBKEY"); | |
367 | _remote_ssh_passphrase = cl_getenv("GITTEST_REMOTE_SSH_PASSPHRASE"); | |
84efffc3 | 368 | _remote_default = cl_getenv("GITTEST_REMOTE_DEFAULT"); |
22a2d3d5 | 369 | _remote_expectcontinue = cl_getenv("GITTEST_REMOTE_EXPECTCONTINUE"); |
613d5eb9 PK |
370 | _remote = NULL; |
371 | ||
0f65733b VM |
372 | /* Skip the test if we're missing the remote URL */ |
373 | if (!_remote_url) | |
374 | cl_skip(); | |
613d5eb9 | 375 | |
22a2d3d5 UG |
376 | if (_remote_expectcontinue) |
377 | git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 1); | |
378 | ||
0f65733b | 379 | cl_git_pass(git_remote_create(&_remote, _repo, "test", _remote_url)); |
613d5eb9 | 380 | |
0f65733b | 381 | record_callbacks_data_clear(&_record_cbs_data); |
613d5eb9 | 382 | |
07bd3e57 | 383 | cl_git_pass(git_remote_connect(_remote, GIT_DIRECTION_PUSH, &_record_cbs, NULL, NULL)); |
613d5eb9 | 384 | |
0f65733b VM |
385 | /* Clean up previously pushed branches. Fails if receive.denyDeletes is |
386 | * set on the remote. Also, on Git 1.7.0 and newer, you must run | |
387 | * 'git config receive.denyDeleteCurrent ignore' in the remote repo in | |
388 | * order to delete the remote branch pointed to by HEAD (usually master). | |
389 | * See: https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.0.txt | |
390 | */ | |
391 | cl_git_pass(git_remote_ls(&heads, &heads_len, _remote)); | |
392 | cl_git_pass(create_deletion_refspecs(&delete_specs, heads, heads_len)); | |
393 | if (delete_specs.length) { | |
fe794b2e CMN |
394 | git_strarray arr = { |
395 | (char **) delete_specs.contents, | |
396 | delete_specs.length, | |
397 | }; | |
613d5eb9 | 398 | |
0f69b41d CMN |
399 | memcpy(&push_opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks)); |
400 | cl_git_pass(git_remote_upload(_remote, &arr, &push_opts)); | |
0f65733b VM |
401 | } |
402 | ||
403 | git_remote_disconnect(_remote); | |
6c7cee42 | 404 | git_vector_free_deep(&delete_specs); |
613d5eb9 | 405 | |
0f65733b | 406 | /* Now that we've deleted everything, fetch from the remote */ |
0f69b41d CMN |
407 | memcpy(&fetch_opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks)); |
408 | cl_git_pass(git_remote_fetch(_remote, NULL, &fetch_opts, NULL)); | |
613d5eb9 PK |
409 | } |
410 | ||
6443eaf2 | 411 | void test_online_push__cleanup(void) |
613d5eb9 PK |
412 | { |
413 | if (_remote) | |
414 | git_remote_free(_remote); | |
c4e3e797 BS |
415 | _remote = NULL; |
416 | ||
e069c621 ET |
417 | git__free(_remote_url); |
418 | git__free(_remote_user); | |
419 | git__free(_remote_pass); | |
420 | git__free(_remote_ssh_key); | |
421 | git__free(_remote_ssh_pubkey); | |
422 | git__free(_remote_ssh_passphrase); | |
423 | git__free(_remote_default); | |
22a2d3d5 | 424 | git__free(_remote_expectcontinue); |
e069c621 | 425 | |
c4e3e797 BS |
426 | /* Freed by cl_git_sandbox_cleanup */ |
427 | _repo = NULL; | |
613d5eb9 | 428 | |
22a2d3d5 UG |
429 | git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 0); |
430 | ||
613d5eb9 PK |
431 | record_callbacks_data_clear(&_record_cbs_data); |
432 | ||
433 | cl_fixture_cleanup("testrepo.git"); | |
434 | cl_git_sandbox_cleanup(); | |
435 | } | |
436 | ||
11bd7a03 RB |
437 | static int push_pack_progress_cb( |
438 | int stage, unsigned int current, unsigned int total, void* payload) | |
b176eded | 439 | { |
6eb9e39c | 440 | record_callbacks_data *data = (record_callbacks_data *) payload; |
7baa7631 | 441 | GIT_UNUSED(stage); GIT_UNUSED(current); GIT_UNUSED(total); |
6eb9e39c CMN |
442 | if (data->pack_progress_calls < 0) |
443 | return data->pack_progress_calls; | |
444 | ||
445 | data->pack_progress_calls++; | |
5b188225 | 446 | return 0; |
b176eded JM |
447 | } |
448 | ||
11bd7a03 RB |
449 | static int push_transfer_progress_cb( |
450 | unsigned int current, unsigned int total, size_t bytes, void* payload) | |
b176eded | 451 | { |
6eb9e39c | 452 | record_callbacks_data *data = (record_callbacks_data *) payload; |
af302aca | 453 | GIT_UNUSED(current); GIT_UNUSED(total); GIT_UNUSED(bytes); |
6eb9e39c CMN |
454 | if (data->transfer_progress_calls < 0) |
455 | return data->transfer_progress_calls; | |
456 | ||
457 | data->transfer_progress_calls++; | |
5b188225 | 458 | return 0; |
b176eded JM |
459 | } |
460 | ||
613d5eb9 PK |
461 | /** |
462 | * Calls push and relists refs on remote to verify success. | |
156cfec0 | 463 | * |
613d5eb9 PK |
464 | * @param refspecs refspecs to push |
465 | * @param refspecs_len length of refspecs | |
466 | * @param expected_refs expected remote refs after push | |
467 | * @param expected_refs_len length of expected_refs | |
468 | * @param expected_ret expected return value from git_push_finish() | |
b176eded | 469 | * @param check_progress_cb Check that the push progress callbacks are called |
613d5eb9 | 470 | */ |
11bd7a03 RB |
471 | static void do_push( |
472 | const char *refspecs[], size_t refspecs_len, | |
613d5eb9 | 473 | push_status expected_statuses[], size_t expected_statuses_len, |
11bd7a03 | 474 | expected_ref expected_refs[], size_t expected_refs_len, |
f70cfd34 | 475 | int expected_ret, int check_progress_cb, int check_update_tips_cb) |
613d5eb9 | 476 | { |
b8b897bb | 477 | git_push_options opts = GIT_PUSH_OPTIONS_INIT; |
613d5eb9 | 478 | size_t i; |
6eb9e39c | 479 | int error; |
64e3e6d4 | 480 | git_strarray specs = {0}; |
6eb9e39c | 481 | record_callbacks_data *data; |
613d5eb9 PK |
482 | |
483 | if (_remote) { | |
b8b897bb PK |
484 | /* Auto-detect the number of threads to use */ |
485 | opts.pb_parallelism = 0; | |
486 | ||
8f0104ec CMN |
487 | memcpy(&opts.callbacks, &_record_cbs, sizeof(git_remote_callbacks)); |
488 | data = opts.callbacks.payload; | |
613d5eb9 | 489 | |
8f0104ec CMN |
490 | opts.callbacks.pack_progress = push_pack_progress_cb; |
491 | opts.callbacks.push_transfer_progress = push_transfer_progress_cb; | |
492 | opts.callbacks.push_update_reference = record_push_status_cb; | |
11bd7a03 | 493 | |
64e3e6d4 CMN |
494 | if (refspecs_len) { |
495 | specs.count = refspecs_len; | |
496 | specs.strings = git__calloc(refspecs_len, sizeof(char *)); | |
497 | cl_assert(specs.strings); | |
11bd7a03 | 498 | } |
b176eded | 499 | |
613d5eb9 | 500 | for (i = 0; i < refspecs_len; i++) |
6eb9e39c CMN |
501 | specs.strings[i] = (char *) refspecs[i]; |
502 | ||
503 | /* if EUSER, then abort in transfer */ | |
504 | if (check_progress_cb && expected_ret == GIT_EUSER) | |
505 | data->transfer_progress_calls = GIT_EUSER; | |
506 | ||
412a3808 | 507 | error = git_remote_push(_remote, &specs, &opts); |
6eb9e39c | 508 | git__free(specs.strings); |
613d5eb9 PK |
509 | |
510 | if (expected_ret < 0) { | |
6eb9e39c | 511 | cl_git_fail_with(expected_ret, error); |
11bd7a03 | 512 | } else { |
6eb9e39c | 513 | cl_git_pass(error); |
613d5eb9 PK |
514 | } |
515 | ||
6eb9e39c CMN |
516 | if (check_progress_cb && expected_ret == 0) { |
517 | cl_assert(data->pack_progress_calls > 0); | |
518 | cl_assert(data->transfer_progress_calls > 0); | |
b176eded JM |
519 | } |
520 | ||
6eb9e39c | 521 | do_verify_push_status(data, expected_statuses, expected_statuses_len); |
613d5eb9 | 522 | |
613d5eb9 | 523 | verify_refs(_remote, expected_refs, expected_refs_len); |
1d645aab JM |
524 | verify_tracking_branches(_remote, expected_refs, expected_refs_len); |
525 | ||
f70cfd34 JG |
526 | if (check_update_tips_cb) |
527 | verify_update_tips_callback(_remote, expected_refs, expected_refs_len); | |
528 | ||
613d5eb9 | 529 | } |
491cecfe | 530 | |
613d5eb9 PK |
531 | } |
532 | ||
533 | /* Call push_finish() without ever calling git_push_add_refspec() */ | |
6443eaf2 | 534 | void test_online_push__noop(void) |
613d5eb9 | 535 | { |
f70cfd34 | 536 | do_push(NULL, 0, NULL, 0, NULL, 0, 0, 0, 1); |
613d5eb9 PK |
537 | } |
538 | ||
6443eaf2 | 539 | void test_online_push__b1(void) |
613d5eb9 PK |
540 | { |
541 | const char *specs[] = { "refs/heads/b1:refs/heads/b1" }; | |
9d41984c | 542 | push_status exp_stats[] = { { "refs/heads/b1", 1 } }; |
613d5eb9 PK |
543 | expected_ref exp_refs[] = { { "refs/heads/b1", &_oid_b1 } }; |
544 | do_push(specs, ARRAY_SIZE(specs), | |
545 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 546 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
613d5eb9 PK |
547 | } |
548 | ||
6443eaf2 | 549 | void test_online_push__b2(void) |
613d5eb9 PK |
550 | { |
551 | const char *specs[] = { "refs/heads/b2:refs/heads/b2" }; | |
9d41984c | 552 | push_status exp_stats[] = { { "refs/heads/b2", 1 } }; |
613d5eb9 PK |
553 | expected_ref exp_refs[] = { { "refs/heads/b2", &_oid_b2 } }; |
554 | do_push(specs, ARRAY_SIZE(specs), | |
555 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 556 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
613d5eb9 PK |
557 | } |
558 | ||
6443eaf2 | 559 | void test_online_push__b3(void) |
613d5eb9 PK |
560 | { |
561 | const char *specs[] = { "refs/heads/b3:refs/heads/b3" }; | |
9d41984c | 562 | push_status exp_stats[] = { { "refs/heads/b3", 1 } }; |
613d5eb9 PK |
563 | expected_ref exp_refs[] = { { "refs/heads/b3", &_oid_b3 } }; |
564 | do_push(specs, ARRAY_SIZE(specs), | |
565 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 566 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
613d5eb9 PK |
567 | } |
568 | ||
6443eaf2 | 569 | void test_online_push__b4(void) |
613d5eb9 PK |
570 | { |
571 | const char *specs[] = { "refs/heads/b4:refs/heads/b4" }; | |
9d41984c | 572 | push_status exp_stats[] = { { "refs/heads/b4", 1 } }; |
613d5eb9 PK |
573 | expected_ref exp_refs[] = { { "refs/heads/b4", &_oid_b4 } }; |
574 | do_push(specs, ARRAY_SIZE(specs), | |
575 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 576 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
613d5eb9 PK |
577 | } |
578 | ||
6443eaf2 | 579 | void test_online_push__b5(void) |
613d5eb9 PK |
580 | { |
581 | const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; | |
9d41984c | 582 | push_status exp_stats[] = { { "refs/heads/b5", 1 } }; |
613d5eb9 PK |
583 | expected_ref exp_refs[] = { { "refs/heads/b5", &_oid_b5 } }; |
584 | do_push(specs, ARRAY_SIZE(specs), | |
585 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 586 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
613d5eb9 PK |
587 | } |
588 | ||
11bd7a03 RB |
589 | void test_online_push__b5_cancel(void) |
590 | { | |
591 | const char *specs[] = { "refs/heads/b5:refs/heads/b5" }; | |
f70cfd34 | 592 | do_push(specs, ARRAY_SIZE(specs), NULL, 0, NULL, 0, GIT_EUSER, 1, 1); |
11bd7a03 RB |
593 | } |
594 | ||
6443eaf2 | 595 | void test_online_push__multi(void) |
613d5eb9 | 596 | { |
491cecfe BS |
597 | git_reflog *log; |
598 | const git_reflog_entry *entry; | |
599 | ||
613d5eb9 PK |
600 | const char *specs[] = { |
601 | "refs/heads/b1:refs/heads/b1", | |
602 | "refs/heads/b2:refs/heads/b2", | |
603 | "refs/heads/b3:refs/heads/b3", | |
604 | "refs/heads/b4:refs/heads/b4", | |
605 | "refs/heads/b5:refs/heads/b5" | |
606 | }; | |
607 | push_status exp_stats[] = { | |
9d41984c ET |
608 | { "refs/heads/b1", 1 }, |
609 | { "refs/heads/b2", 1 }, | |
610 | { "refs/heads/b3", 1 }, | |
611 | { "refs/heads/b4", 1 }, | |
612 | { "refs/heads/b5", 1 } | |
613d5eb9 PK |
613 | }; |
614 | expected_ref exp_refs[] = { | |
615 | { "refs/heads/b1", &_oid_b1 }, | |
616 | { "refs/heads/b2", &_oid_b2 }, | |
617 | { "refs/heads/b3", &_oid_b3 }, | |
618 | { "refs/heads/b4", &_oid_b4 }, | |
619 | { "refs/heads/b5", &_oid_b5 } | |
620 | }; | |
621 | do_push(specs, ARRAY_SIZE(specs), | |
622 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 623 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
491cecfe BS |
624 | |
625 | cl_git_pass(git_reflog_read(&log, _repo, "refs/remotes/test/b1")); | |
626 | entry = git_reflog_entry_byindex(log, 0); | |
3094102f | 627 | if (entry) { |
412a3808 | 628 | cl_assert_equal_s("update by push", git_reflog_entry_message(entry)); |
3094102f BS |
629 | cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email); |
630 | } | |
491cecfe BS |
631 | |
632 | git_reflog_free(log); | |
613d5eb9 PK |
633 | } |
634 | ||
6443eaf2 | 635 | void test_online_push__implicit_tgt(void) |
613d5eb9 | 636 | { |
aad638f3 | 637 | const char *specs1[] = { "refs/heads/b1" }; |
9d41984c | 638 | push_status exp_stats1[] = { { "refs/heads/b1", 1 } }; |
613d5eb9 PK |
639 | expected_ref exp_refs1[] = { { "refs/heads/b1", &_oid_b1 } }; |
640 | ||
aad638f3 | 641 | const char *specs2[] = { "refs/heads/b2" }; |
9d41984c | 642 | push_status exp_stats2[] = { { "refs/heads/b2", 1 } }; |
613d5eb9 PK |
643 | expected_ref exp_refs2[] = { |
644 | { "refs/heads/b1", &_oid_b1 }, | |
645 | { "refs/heads/b2", &_oid_b2 } | |
646 | }; | |
647 | ||
648 | do_push(specs1, ARRAY_SIZE(specs1), | |
649 | exp_stats1, ARRAY_SIZE(exp_stats1), | |
f70cfd34 | 650 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); |
613d5eb9 PK |
651 | do_push(specs2, ARRAY_SIZE(specs2), |
652 | exp_stats2, ARRAY_SIZE(exp_stats2), | |
f70cfd34 | 653 | exp_refs2, ARRAY_SIZE(exp_refs2), 0, 0, 0); |
613d5eb9 PK |
654 | } |
655 | ||
6443eaf2 | 656 | void test_online_push__fast_fwd(void) |
613d5eb9 PK |
657 | { |
658 | /* Fast forward b1 in tgt from _oid_b1 to _oid_b6. */ | |
659 | ||
660 | const char *specs_init[] = { "refs/heads/b1:refs/heads/b1" }; | |
9d41984c | 661 | push_status exp_stats_init[] = { { "refs/heads/b1", 1 } }; |
613d5eb9 PK |
662 | expected_ref exp_refs_init[] = { { "refs/heads/b1", &_oid_b1 } }; |
663 | ||
664 | const char *specs_ff[] = { "refs/heads/b6:refs/heads/b1" }; | |
9d41984c | 665 | push_status exp_stats_ff[] = { { "refs/heads/b1", 1 } }; |
613d5eb9 PK |
666 | expected_ref exp_refs_ff[] = { { "refs/heads/b1", &_oid_b6 } }; |
667 | ||
668 | /* Do a force push to reset b1 in target back to _oid_b1 */ | |
669 | const char *specs_reset[] = { "+refs/heads/b1:refs/heads/b1" }; | |
670 | /* Force should have no effect on a fast forward push */ | |
671 | const char *specs_ff_force[] = { "+refs/heads/b6:refs/heads/b1" }; | |
672 | ||
673 | do_push(specs_init, ARRAY_SIZE(specs_init), | |
674 | exp_stats_init, ARRAY_SIZE(exp_stats_init), | |
f70cfd34 | 675 | exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 1, 1); |
613d5eb9 PK |
676 | |
677 | do_push(specs_ff, ARRAY_SIZE(specs_ff), | |
678 | exp_stats_ff, ARRAY_SIZE(exp_stats_ff), | |
f70cfd34 | 679 | exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); |
613d5eb9 PK |
680 | |
681 | do_push(specs_reset, ARRAY_SIZE(specs_reset), | |
682 | exp_stats_init, ARRAY_SIZE(exp_stats_init), | |
f70cfd34 | 683 | exp_refs_init, ARRAY_SIZE(exp_refs_init), 0, 0, 0); |
613d5eb9 PK |
684 | |
685 | do_push(specs_ff_force, ARRAY_SIZE(specs_ff_force), | |
686 | exp_stats_ff, ARRAY_SIZE(exp_stats_ff), | |
f70cfd34 | 687 | exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0, 0, 0); |
613d5eb9 PK |
688 | } |
689 | ||
abeefbbe MS |
690 | void test_online_push__tag_commit(void) |
691 | { | |
692 | const char *specs[] = { "refs/tags/tag-commit:refs/tags/tag-commit" }; | |
9d41984c | 693 | push_status exp_stats[] = { { "refs/tags/tag-commit", 1 } }; |
abeefbbe MS |
694 | expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } }; |
695 | do_push(specs, ARRAY_SIZE(specs), | |
696 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 697 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
abeefbbe MS |
698 | } |
699 | ||
700 | void test_online_push__tag_tree(void) | |
701 | { | |
702 | const char *specs[] = { "refs/tags/tag-tree:refs/tags/tag-tree" }; | |
9d41984c | 703 | push_status exp_stats[] = { { "refs/tags/tag-tree", 1 } }; |
abeefbbe MS |
704 | expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } }; |
705 | do_push(specs, ARRAY_SIZE(specs), | |
706 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 707 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
abeefbbe MS |
708 | } |
709 | ||
710 | void test_online_push__tag_blob(void) | |
711 | { | |
712 | const char *specs[] = { "refs/tags/tag-blob:refs/tags/tag-blob" }; | |
9d41984c | 713 | push_status exp_stats[] = { { "refs/tags/tag-blob", 1 } }; |
abeefbbe MS |
714 | expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } }; |
715 | do_push(specs, ARRAY_SIZE(specs), | |
716 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 717 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
abeefbbe MS |
718 | } |
719 | ||
720 | void test_online_push__tag_lightweight(void) | |
721 | { | |
722 | const char *specs[] = { "refs/tags/tag-lightweight:refs/tags/tag-lightweight" }; | |
9d41984c | 723 | push_status exp_stats[] = { { "refs/tags/tag-lightweight", 1 } }; |
abeefbbe MS |
724 | expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } }; |
725 | do_push(specs, ARRAY_SIZE(specs), | |
726 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 727 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
abeefbbe MS |
728 | } |
729 | ||
1c13b0bf ET |
730 | void test_online_push__tag_to_tag(void) |
731 | { | |
732 | const char *specs[] = { "refs/tags/tag-tag:refs/tags/tag-tag" }; | |
9d41984c | 733 | push_status exp_stats[] = { { "refs/tags/tag-tag", 1 } }; |
1c13b0bf ET |
734 | expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } }; |
735 | do_push(specs, ARRAY_SIZE(specs), | |
736 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 737 | exp_refs, ARRAY_SIZE(exp_refs), 0, 0, 0); |
1c13b0bf ET |
738 | } |
739 | ||
6443eaf2 | 740 | void test_online_push__force(void) |
613d5eb9 PK |
741 | { |
742 | const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"}; | |
9d41984c | 743 | push_status exp_stats1[] = { { "refs/heads/tgt", 1 } }; |
613d5eb9 PK |
744 | expected_ref exp_refs1[] = { { "refs/heads/tgt", &_oid_b3 } }; |
745 | ||
746 | const char *specs2[] = {"refs/heads/b4:refs/heads/tgt"}; | |
747 | ||
748 | const char *specs2_force[] = {"+refs/heads/b4:refs/heads/tgt"}; | |
9d41984c | 749 | push_status exp_stats2_force[] = { { "refs/heads/tgt", 1 } }; |
613d5eb9 PK |
750 | expected_ref exp_refs2_force[] = { { "refs/heads/tgt", &_oid_b4 } }; |
751 | ||
752 | do_push(specs1, ARRAY_SIZE(specs1), | |
753 | exp_stats1, ARRAY_SIZE(exp_stats1), | |
f70cfd34 | 754 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); |
613d5eb9 PK |
755 | |
756 | do_push(specs2, ARRAY_SIZE(specs2), | |
757 | NULL, 0, | |
f70cfd34 | 758 | exp_refs1, ARRAY_SIZE(exp_refs1), GIT_ENONFASTFORWARD, 0, 0); |
613d5eb9 PK |
759 | |
760 | /* Non-fast-forward update with force should pass. */ | |
f70cfd34 | 761 | record_callbacks_data_clear(&_record_cbs_data); |
613d5eb9 PK |
762 | do_push(specs2_force, ARRAY_SIZE(specs2_force), |
763 | exp_stats2_force, ARRAY_SIZE(exp_stats2_force), | |
f70cfd34 | 764 | exp_refs2_force, ARRAY_SIZE(exp_refs2_force), 0, 1, 1); |
613d5eb9 PK |
765 | } |
766 | ||
6443eaf2 | 767 | void test_online_push__delete(void) |
613d5eb9 PK |
768 | { |
769 | const char *specs1[] = { | |
770 | "refs/heads/b1:refs/heads/tgt1", | |
771 | "refs/heads/b1:refs/heads/tgt2" | |
772 | }; | |
773 | push_status exp_stats1[] = { | |
9d41984c ET |
774 | { "refs/heads/tgt1", 1 }, |
775 | { "refs/heads/tgt2", 1 } | |
613d5eb9 PK |
776 | }; |
777 | expected_ref exp_refs1[] = { | |
778 | { "refs/heads/tgt1", &_oid_b1 }, | |
779 | { "refs/heads/tgt2", &_oid_b1 } | |
780 | }; | |
781 | ||
782 | const char *specs_del_fake[] = { ":refs/heads/fake" }; | |
783 | /* Force has no effect for delete. */ | |
784 | const char *specs_del_fake_force[] = { "+:refs/heads/fake" }; | |
9d41984c | 785 | push_status exp_stats_fake[] = { { "refs/heads/fake", 1 } }; |
613d5eb9 PK |
786 | |
787 | const char *specs_delete[] = { ":refs/heads/tgt1" }; | |
9d41984c | 788 | push_status exp_stats_delete[] = { { "refs/heads/tgt1", 1 } }; |
613d5eb9 PK |
789 | expected_ref exp_refs_delete[] = { { "refs/heads/tgt2", &_oid_b1 } }; |
790 | /* Force has no effect for delete. */ | |
791 | const char *specs_delete_force[] = { "+:refs/heads/tgt1" }; | |
792 | ||
793 | do_push(specs1, ARRAY_SIZE(specs1), | |
794 | exp_stats1, ARRAY_SIZE(exp_stats1), | |
f70cfd34 | 795 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 1, 1); |
613d5eb9 | 796 | |
d73d52df CW |
797 | /* When deleting a non-existent branch, the git client sends zero for both |
798 | * the old and new commit id. This should succeed on the server with the | |
799 | * same status report as if the branch were actually deleted. The server | |
800 | * returns a warning on the side-band iff the side-band is supported. | |
801 | * Since libgit2 doesn't support the side-band yet, there are no warnings. | |
613d5eb9 PK |
802 | */ |
803 | do_push(specs_del_fake, ARRAY_SIZE(specs_del_fake), | |
d73d52df | 804 | exp_stats_fake, 1, |
f70cfd34 | 805 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); |
613d5eb9 | 806 | do_push(specs_del_fake_force, ARRAY_SIZE(specs_del_fake_force), |
d73d52df | 807 | exp_stats_fake, 1, |
f70cfd34 | 808 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); |
613d5eb9 PK |
809 | |
810 | /* Delete one of the pushed branches. */ | |
811 | do_push(specs_delete, ARRAY_SIZE(specs_delete), | |
812 | exp_stats_delete, ARRAY_SIZE(exp_stats_delete), | |
f70cfd34 | 813 | exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); |
613d5eb9 PK |
814 | |
815 | /* Re-push branches and retry delete with force. */ | |
816 | do_push(specs1, ARRAY_SIZE(specs1), | |
817 | exp_stats1, ARRAY_SIZE(exp_stats1), | |
f70cfd34 | 818 | exp_refs1, ARRAY_SIZE(exp_refs1), 0, 0, 0); |
613d5eb9 PK |
819 | do_push(specs_delete_force, ARRAY_SIZE(specs_delete_force), |
820 | exp_stats_delete, ARRAY_SIZE(exp_stats_delete), | |
f70cfd34 | 821 | exp_refs_delete, ARRAY_SIZE(exp_refs_delete), 0, 0, 0); |
613d5eb9 PK |
822 | } |
823 | ||
6443eaf2 | 824 | void test_online_push__bad_refspecs(void) |
613d5eb9 PK |
825 | { |
826 | /* All classes of refspecs that should be rejected by | |
827 | * git_push_add_refspec() should go in this test. | |
828 | */ | |
fe794b2e CMN |
829 | char *specs = { |
830 | "b6:b6", | |
831 | }; | |
832 | git_strarray arr = { | |
833 | &specs, | |
834 | 1, | |
835 | }; | |
613d5eb9 PK |
836 | |
837 | if (_remote) { | |
fe794b2e | 838 | cl_git_fail(git_remote_upload(_remote, &arr, NULL)); |
613d5eb9 PK |
839 | } |
840 | } | |
841 | ||
6443eaf2 | 842 | void test_online_push__expressions(void) |
613d5eb9 PK |
843 | { |
844 | /* TODO: Expressions in refspecs doesn't actually work yet */ | |
845 | const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" }; | |
846 | ||
613d5eb9 PK |
847 | /* TODO: Find a more precise way of checking errors than a exit code of -1. */ |
848 | do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), | |
849 | NULL, 0, | |
f70cfd34 | 850 | NULL, 0, -1, 0, 0); |
613d5eb9 | 851 | } |
087f64d3 | 852 | |
abeefbbe | 853 | void test_online_push__notes(void) |
087f64d3 JM |
854 | { |
855 | git_oid note_oid, *target_oid, expected_oid; | |
856 | git_signature *signature; | |
857 | const char *specs[] = { "refs/notes/commits:refs/notes/commits" }; | |
9d41984c | 858 | push_status exp_stats[] = { { "refs/notes/commits", 1 } }; |
087f64d3 | 859 | expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; |
0f29e967 | 860 | const char *specs_del[] = { ":refs/notes/commits" }; |
0f29e967 | 861 | |
087f64d3 JM |
862 | git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb"); |
863 | ||
864 | target_oid = &_oid_b6; | |
865 | ||
866 | /* Create note to push */ | |
867 | cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */ | |
21083a71 | 868 | cl_git_pass(git_note_create(¬e_oid, _repo, NULL, signature, signature, target_oid, "hello world\n", 0)); |
087f64d3 JM |
869 | |
870 | do_push(specs, ARRAY_SIZE(specs), | |
871 | exp_stats, ARRAY_SIZE(exp_stats), | |
f70cfd34 | 872 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); |
087f64d3 | 873 | |
0f29e967 ET |
874 | /* And make sure to delete the note */ |
875 | ||
876 | do_push(specs_del, ARRAY_SIZE(specs_del), | |
877 | exp_stats, 1, | |
aff70018 | 878 | NULL, 0, 0, 0, 0); |
0f29e967 | 879 | |
087f64d3 JM |
880 | git_signature_free(signature); |
881 | } | |
64e3e6d4 CMN |
882 | |
883 | void test_online_push__configured(void) | |
884 | { | |
885 | git_oid note_oid, *target_oid, expected_oid; | |
886 | git_signature *signature; | |
77254990 | 887 | git_remote *old_remote; |
64e3e6d4 CMN |
888 | const char *specs[] = { "refs/notes/commits:refs/notes/commits" }; |
889 | push_status exp_stats[] = { { "refs/notes/commits", 1 } }; | |
890 | expected_ref exp_refs[] = { { "refs/notes/commits", &expected_oid } }; | |
891 | const char *specs_del[] = { ":refs/notes/commits" }; | |
892 | ||
893 | git_oid_fromstr(&expected_oid, "8461a99b27b7043e58ff6e1f5d2cf07d282534fb"); | |
894 | ||
895 | target_oid = &_oid_b6; | |
896 | ||
77254990 CMN |
897 | cl_git_pass(git_remote_add_push(_repo, git_remote_name(_remote), specs[0])); |
898 | old_remote = _remote; | |
899 | cl_git_pass(git_remote_lookup(&_remote, _repo, git_remote_name(_remote))); | |
900 | git_remote_free(old_remote); | |
64e3e6d4 CMN |
901 | |
902 | /* Create note to push */ | |
903 | cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */ | |
21083a71 | 904 | cl_git_pass(git_note_create(¬e_oid, _repo, NULL, signature, signature, target_oid, "hello world\n", 0)); |
64e3e6d4 CMN |
905 | |
906 | do_push(NULL, 0, | |
907 | exp_stats, ARRAY_SIZE(exp_stats), | |
908 | exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); | |
909 | ||
910 | /* And make sure to delete the note */ | |
911 | ||
912 | do_push(specs_del, ARRAY_SIZE(specs_del), | |
913 | exp_stats, 1, | |
914 | NULL, 0, 0, 0, 0); | |
915 | ||
916 | git_signature_free(signature); | |
917 | } |