]> git.proxmox.com Git - libgit2.git/blob - tests/network/remote/local.c
99b91c5d06f9698a37615b5e5a7c74996c7f02aa
[libgit2.git] / tests / network / remote / local.c
1 #include "clar_libgit2.h"
2 #include "buffer.h"
3 #include "path.h"
4 #include "posix.h"
5 #include "git2/sys/repository.h"
6
7 static git_repository *repo;
8 static git_buf file_path_buf = GIT_BUF_INIT;
9 static git_remote *remote;
10
11 static char *push_refspec_strings[] = {
12 "refs/heads/master",
13 };
14 static git_strarray push_array = {
15 push_refspec_strings,
16 1,
17 };
18
19 void test_network_remote_local__initialize(void)
20 {
21 cl_git_pass(git_repository_init(&repo, "remotelocal/", 0));
22 cl_git_pass(git_repository_set_ident(repo, "Foo Bar", "foo@example.com"));
23 cl_assert(repo != NULL);
24 }
25
26 void test_network_remote_local__cleanup(void)
27 {
28 git_buf_dispose(&file_path_buf);
29
30 git_remote_free(remote);
31 remote = NULL;
32
33 git_repository_free(repo);
34 repo = NULL;
35
36 cl_fixture_cleanup("remotelocal");
37 }
38
39 static void connect_to_local_repository(const char *local_repository)
40 {
41 git_buf_sets(&file_path_buf, cl_git_path_url(local_repository));
42
43 cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
44 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
45 }
46
47 void test_network_remote_local__connected(void)
48 {
49 connect_to_local_repository(cl_fixture("testrepo.git"));
50 cl_assert(git_remote_connected(remote));
51
52 git_remote_disconnect(remote);
53 cl_assert(!git_remote_connected(remote));
54 }
55
56 void test_network_remote_local__retrieve_advertised_references(void)
57 {
58 const git_remote_head **refs;
59 size_t refs_len;
60
61 connect_to_local_repository(cl_fixture("testrepo.git"));
62
63 cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
64
65 cl_assert_equal_i(refs_len, 28);
66 }
67
68 void test_network_remote_local__retrieve_advertised_before_connect(void)
69 {
70 const git_remote_head **refs;
71 size_t refs_len = 0;
72
73 git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git")));
74
75 cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
76 cl_git_fail(git_remote_ls(&refs, &refs_len, remote));
77 }
78
79 void test_network_remote_local__retrieve_advertised_references_after_disconnect(void)
80 {
81 const git_remote_head **refs;
82 size_t refs_len;
83
84 connect_to_local_repository(cl_fixture("testrepo.git"));
85 git_remote_disconnect(remote);
86
87 cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
88
89 cl_assert_equal_i(refs_len, 28);
90 }
91
92 void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
93 {
94 const git_remote_head **refs;
95 size_t refs_len;
96
97 cl_fixture_sandbox("testrepo.git");
98 cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git"));
99
100 connect_to_local_repository("spaced testrepo.git");
101
102 cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
103
104 cl_assert_equal_i(refs_len, 28);
105
106 git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */
107 remote = NULL;
108
109 cl_fixture_cleanup("spaced testrepo.git");
110 }
111
112 void test_network_remote_local__nested_tags_are_completely_peeled(void)
113 {
114 const git_remote_head **refs;
115 size_t refs_len, i;
116
117 connect_to_local_repository(cl_fixture("testrepo.git"));
118
119 cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
120
121 for (i = 0; i < refs_len; i++) {
122 if (!strcmp(refs[i]->name, "refs/tags/test^{}"))
123 cl_git_pass(git_oid_streq(&refs[i]->oid, "e90810b8df3e80c413d903f631643c716887138d"));
124 }
125 }
126
127 void test_network_remote_local__shorthand_fetch_refspec0(void)
128 {
129 char *refspec_strings[] = {
130 "master:remotes/sloppy/master",
131 "master:boh/sloppy/master",
132 };
133 git_strarray array = {
134 refspec_strings,
135 2,
136 };
137
138 git_reference *ref;
139
140 connect_to_local_repository(cl_fixture("testrepo.git"));
141
142 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
143
144 cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
145 git_reference_free(ref);
146
147 cl_git_pass(git_reference_lookup(&ref, repo, "refs/heads/boh/sloppy/master"));
148 git_reference_free(ref);
149 }
150
151 void test_network_remote_local__shorthand_fetch_refspec1(void)
152 {
153 char *refspec_strings[] = {
154 "master",
155 "hard_tag",
156 };
157 git_strarray array = {
158 refspec_strings,
159 2,
160 };
161
162 git_reference *ref;
163
164 connect_to_local_repository(cl_fixture("testrepo.git"));
165
166 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
167
168 cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
169 cl_git_fail(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
170 }
171
172 void test_network_remote_local__tagopt(void)
173 {
174 git_reference *ref;
175 git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
176
177 cl_git_pass(git_remote_create(&remote, repo, "tagopt", cl_git_path_url(cl_fixture("testrepo.git"))));
178 fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
179 cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
180
181 cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
182 git_reference_free(ref);
183 cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
184 git_reference_free(ref);
185
186 fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
187 cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
188 cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
189 git_reference_free(ref);
190 }
191
192 void test_network_remote_local__push_to_bare_remote(void)
193 {
194 char *refspec_strings[] = {
195 "master:master",
196 };
197 git_strarray array = {
198 refspec_strings,
199 1,
200 };
201
202 /* Should be able to push to a bare remote */
203 git_remote *localremote;
204
205 /* Get some commits */
206 connect_to_local_repository(cl_fixture("testrepo.git"));
207 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
208
209 /* Set up an empty bare repo to push into */
210 {
211 git_repository *localbarerepo;
212 cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
213 git_repository_free(localbarerepo);
214 }
215
216 /* Connect to the bare repo */
217 cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localbare.git"));
218 cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
219
220 /* Try to push */
221 cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
222
223 /* Clean up */
224 git_remote_free(localremote);
225 cl_fixture_cleanup("localbare.git");
226 }
227
228 void test_network_remote_local__push_to_bare_remote_with_file_url(void)
229 {
230 char *refspec_strings[] = {
231 "master:master",
232 };
233 git_strarray array = {
234 refspec_strings,
235 1,
236 };
237 /* Should be able to push to a bare remote */
238 git_remote *localremote;
239 const char *url;
240
241 /* Get some commits */
242 connect_to_local_repository(cl_fixture("testrepo.git"));
243 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
244
245 /* Set up an empty bare repo to push into */
246 {
247 git_repository *localbarerepo;
248 cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
249 git_repository_free(localbarerepo);
250 }
251
252 /* Create a file URL */
253 url = cl_git_path_url("./localbare.git");
254
255 /* Connect to the bare repo */
256 cl_git_pass(git_remote_create_anonymous(&localremote, repo, url));
257 cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
258
259 /* Try to push */
260 cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
261
262 /* Clean up */
263 git_remote_free(localremote);
264 cl_fixture_cleanup("localbare.git");
265 }
266
267
268 void test_network_remote_local__push_to_non_bare_remote(void)
269 {
270 char *refspec_strings[] = {
271 "master:master",
272 };
273 git_strarray array = {
274 refspec_strings,
275 1,
276 };
277 /* Shouldn't be able to push to a non-bare remote */
278 git_remote *localremote;
279 git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
280
281 /* Get some commits */
282 connect_to_local_repository(cl_fixture("testrepo.git"));
283 cl_git_pass(git_remote_fetch(remote, &array, &fetch_opts, NULL));
284
285 /* Set up an empty non-bare repo to push into */
286 {
287 git_repository *remoterepo = NULL;
288 cl_git_pass(git_repository_init(&remoterepo, "localnonbare", 0));
289 git_repository_free(remoterepo);
290 }
291
292 /* Connect to the bare repo */
293 cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localnonbare"));
294 cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
295
296 /* Try to push */
297 cl_git_fail_with(GIT_EBAREREPO, git_remote_upload(localremote, &push_array, NULL));
298
299 /* Clean up */
300 git_remote_free(localremote);
301 cl_fixture_cleanup("localbare.git");
302 }
303
304 void test_network_remote_local__fetch(void)
305 {
306 char *refspec_strings[] = {
307 "master:remotes/sloppy/master",
308 };
309 git_strarray array = {
310 refspec_strings,
311 1,
312 };
313
314 git_reflog *log;
315 const git_reflog_entry *entry;
316 git_reference *ref;
317
318 connect_to_local_repository(cl_fixture("testrepo.git"));
319
320 cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
321
322 cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
323 git_reference_free(ref);
324
325 cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
326 cl_assert_equal_i(1, git_reflog_entrycount(log));
327 entry = git_reflog_entry_byindex(log, 0);
328 cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
329 cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
330
331 git_reflog_free(log);
332 }
333
334 void test_network_remote_local__reflog(void)
335 {
336 char *refspec_strings[] = {
337 "master:remotes/sloppy/master",
338 };
339 git_strarray array = {
340 refspec_strings,
341 1,
342 };
343
344 git_reflog *log;
345 const git_reflog_entry *entry;
346
347 connect_to_local_repository(cl_fixture("testrepo.git"));
348
349 cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
350
351 cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
352 cl_assert_equal_i(1, git_reflog_entrycount(log));
353 entry = git_reflog_entry_byindex(log, 0);
354 cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
355 cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
356
357 git_reflog_free(log);
358 }
359
360 void test_network_remote_local__fetch_default_reflog_message(void)
361 {
362 char *refspec_strings[] = {
363 "master:remotes/sloppy/master",
364 };
365 git_strarray array = {
366 refspec_strings,
367 1,
368 };
369
370 git_reflog *log;
371 const git_reflog_entry *entry;
372 char expected_reflog_msg[1024];
373
374 connect_to_local_repository(cl_fixture("testrepo.git"));
375
376 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
377
378 cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
379 cl_assert_equal_i(1, git_reflog_entrycount(log));
380 entry = git_reflog_entry_byindex(log, 0);
381 cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
382
383 sprintf(expected_reflog_msg, "fetch %s", git_remote_url(remote));
384 cl_assert_equal_s(expected_reflog_msg, git_reflog_entry_message(entry));
385
386 git_reflog_free(log);
387 }
388
389 void test_network_remote_local__opportunistic_update(void)
390 {
391 git_reference *ref;
392 char *refspec_strings[] = {
393 "master",
394 };
395 git_strarray array = {
396 refspec_strings,
397 1,
398 };
399
400 /* this remote has a passive refspec of "refs/heads/<star>:refs/remotes/origin/<star>" */
401 cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
402 /* and we pass the active refspec "master" */
403 cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
404
405 /* and we expect that to update our copy of origin's master */
406 cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
407 git_reference_free(ref);
408 }
409
410 void test_network_remote_local__update_tips_for_new_remote(void) {
411 git_repository *src_repo;
412 git_repository *dst_repo;
413 git_remote *new_remote;
414 git_reference* branch;
415
416 /* Copy test repo */
417 cl_fixture_sandbox("testrepo.git");
418 cl_git_pass(git_repository_open(&src_repo, "testrepo.git"));
419
420 /* Set up an empty bare repo to push into */
421 cl_git_pass(git_repository_init(&dst_repo, "./localbare.git", 1));
422
423 /* Push to bare repo */
424 cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git"));
425 cl_git_pass(git_remote_push(new_remote, &push_array, NULL));
426 /* Make sure remote branch has been created */
427 cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE));
428
429 git_reference_free(branch);
430 git_remote_free(new_remote);
431 git_repository_free(dst_repo);
432 cl_fixture_cleanup("localbare.git");
433 git_repository_free(src_repo);
434 cl_fixture_cleanup("testrepo.git");
435 }
436
437 void test_network_remote_local__push_delete(void)
438 {
439 git_repository *src_repo;
440 git_repository *dst_repo;
441 git_remote *remote;
442 git_reference *ref;
443 char *spec_push[] = { "refs/heads/master" };
444 char *spec_delete[] = { ":refs/heads/master" };
445 git_strarray specs = {
446 spec_push,
447 1,
448 };
449
450 src_repo = cl_git_sandbox_init("testrepo.git");
451 cl_git_pass(git_repository_init(&dst_repo, "target.git", 1));
452
453 cl_git_pass(git_remote_create(&remote, src_repo, "origin", "./target.git"));
454
455 /* Push the master branch and verify it's there */
456 cl_git_pass(git_remote_push(remote, &specs, NULL));
457 cl_git_pass(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
458 git_reference_free(ref);
459
460 specs.strings = spec_delete;
461 cl_git_pass(git_remote_push(remote, &specs, NULL));
462 cl_git_fail(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
463
464 git_remote_free(remote);
465 git_repository_free(dst_repo);
466 cl_fixture_cleanup("target.git");
467 cl_git_sandbox_cleanup();
468 }
469
470 void test_network_remote_local__anonymous_remote_inmemory_repo(void)
471 {
472 git_repository *inmemory;
473 git_remote *remote;
474
475 git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git")));
476
477 cl_git_pass(git_repository_new(&inmemory));
478 cl_git_pass(git_remote_create_anonymous(&remote, inmemory, git_buf_cstr(&file_path_buf)));
479 cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
480 cl_assert(git_remote_connected(remote));
481 git_remote_disconnect(remote);
482 git_remote_free(remote);
483 git_repository_free(inmemory);
484 }