1 #include "clar_libgit2.h"
6 static const char* tagger_name
= "Vicent Marti";
7 static const char* tagger_email
= "vicent@github.com";
8 static const char* tagger_message
= "This is my tag.\n\nThere are many tags, but this one is mine\n";
10 static int transfer_cb(const git_indexer_progress
*stats
, void *payload
)
12 int *callcount
= (int*)payload
;
18 static void cleanup_local_repo(void *path
)
20 cl_fixture_cleanup((char *)path
);
23 void test_network_fetchlocal__cleanup(void)
25 cl_git_sandbox_cleanup();
28 void test_network_fetchlocal__complete(void)
33 git_strarray refnames
= {0};
35 const char *url
= cl_git_fixture_url("testrepo.git");
36 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
38 options
.callbacks
.transfer_progress
= transfer_cb
;
39 options
.callbacks
.payload
= &callcount
;
41 cl_set_cleanup(&cleanup_local_repo
, "foo");
42 cl_git_pass(git_repository_init(&repo
, "foo", true));
44 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
45 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
47 cl_git_pass(git_reference_list(&refnames
, repo
));
48 cl_assert_equal_i(20, (int)refnames
.count
);
49 cl_assert(callcount
> 0);
51 git_strarray_dispose(&refnames
);
52 git_remote_free(origin
);
53 git_repository_free(repo
);
56 void test_network_fetchlocal__prune(void)
61 git_strarray refnames
= {0};
63 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
64 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
65 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
67 options
.callbacks
.transfer_progress
= transfer_cb
;
68 options
.callbacks
.payload
= &callcount
;
70 cl_set_cleanup(&cleanup_local_repo
, "foo");
71 cl_git_pass(git_repository_init(&repo
, "foo", true));
73 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
74 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
76 cl_git_pass(git_reference_list(&refnames
, repo
));
77 cl_assert_equal_i(20, (int)refnames
.count
);
78 cl_assert(callcount
> 0);
79 git_strarray_dispose(&refnames
);
80 git_remote_free(origin
);
82 cl_git_pass(git_reference_lookup(&ref
, remote_repo
, "refs/heads/br2"));
83 cl_git_pass(git_reference_delete(ref
));
84 git_reference_free(ref
);
86 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
87 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
88 cl_git_pass(git_remote_prune(origin
, &options
.callbacks
));
90 cl_git_pass(git_reference_list(&refnames
, repo
));
91 cl_assert_equal_i(19, (int)refnames
.count
);
92 git_strarray_dispose(&refnames
);
93 git_remote_free(origin
);
95 cl_git_pass(git_reference_lookup(&ref
, remote_repo
, "refs/heads/packed"));
96 cl_git_pass(git_reference_delete(ref
));
97 git_reference_free(ref
);
99 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
100 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
101 cl_git_pass(git_remote_prune(origin
, &options
.callbacks
));
103 cl_git_pass(git_reference_list(&refnames
, repo
));
104 cl_assert_equal_i(18, (int)refnames
.count
);
105 git_strarray_dispose(&refnames
);
106 git_remote_free(origin
);
108 git_repository_free(repo
);
111 static int update_tips_fail_on_call(const char *ref
, const git_oid
*old
, const git_oid
*new, void *data
)
118 cl_fail("update tips called");
122 static void assert_ref_exists(git_repository
*repo
, const char *name
)
126 cl_git_pass(git_reference_lookup(&ref
, repo
, name
));
127 git_reference_free(ref
);
130 void test_network_fetchlocal__prune_overlapping(void)
132 git_repository
*repo
;
135 git_strarray refnames
= {0};
140 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
141 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
143 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
144 options
.callbacks
.transfer_progress
= transfer_cb
;
145 options
.callbacks
.payload
= &callcount
;
147 cl_git_pass(git_reference_lookup(&ref
, remote_repo
, "refs/heads/master"));
148 git_oid_cpy(&target
, git_reference_target(ref
));
149 git_reference_free(ref
);
150 cl_git_pass(git_reference_create(&ref
, remote_repo
, "refs/pull/42/head", &target
, 1, NULL
));
151 git_reference_free(ref
);
153 cl_set_cleanup(&cleanup_local_repo
, "foo");
154 cl_git_pass(git_repository_init(&repo
, "foo", true));
156 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
158 cl_git_pass(git_repository_config(&config
, repo
));
159 cl_git_pass(git_config_set_bool(config
, "remote.origin.prune", true));
160 cl_git_pass(git_config_set_multivar(config
, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
162 git_remote_free(origin
);
163 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
164 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
166 assert_ref_exists(repo
, "refs/remotes/origin/master");
167 assert_ref_exists(repo
, "refs/remotes/origin/pr/42");
168 cl_git_pass(git_reference_list(&refnames
, repo
));
169 cl_assert_equal_i(21, (int)refnames
.count
);
170 git_strarray_dispose(&refnames
);
172 cl_git_pass(git_config_delete_multivar(config
, "remote.origin.fetch", "refs"));
173 cl_git_pass(git_config_set_multivar(config
, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
174 cl_git_pass(git_config_set_multivar(config
, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
176 git_remote_free(origin
);
177 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
178 options
.callbacks
.update_tips
= update_tips_fail_on_call
;
179 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
181 assert_ref_exists(repo
, "refs/remotes/origin/master");
182 assert_ref_exists(repo
, "refs/remotes/origin/pr/42");
183 cl_git_pass(git_reference_list(&refnames
, repo
));
184 cl_assert_equal_i(21, (int)refnames
.count
);
185 git_strarray_dispose(&refnames
);
187 cl_git_pass(git_config_delete_multivar(config
, "remote.origin.fetch", "refs"));
188 cl_git_pass(git_config_set_multivar(config
, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
189 cl_git_pass(git_config_set_multivar(config
, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
191 git_remote_free(origin
);
192 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
193 options
.callbacks
.update_tips
= update_tips_fail_on_call
;
194 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
196 git_config_free(config
);
197 git_strarray_dispose(&refnames
);
198 git_remote_free(origin
);
199 git_repository_free(repo
);
202 void test_network_fetchlocal__fetchprune(void)
204 git_repository
*repo
;
207 git_strarray refnames
= {0};
210 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
211 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
212 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
214 options
.callbacks
.transfer_progress
= transfer_cb
;
215 options
.callbacks
.payload
= &callcount
;
217 cl_set_cleanup(&cleanup_local_repo
, "foo");
218 cl_git_pass(git_repository_init(&repo
, "foo", true));
220 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
221 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
223 cl_git_pass(git_reference_list(&refnames
, repo
));
224 cl_assert_equal_i(20, (int)refnames
.count
);
225 cl_assert(callcount
> 0);
226 git_strarray_dispose(&refnames
);
227 git_remote_free(origin
);
229 cl_git_pass(git_reference_lookup(&ref
, remote_repo
, "refs/heads/br2"));
230 cl_git_pass(git_reference_delete(ref
));
231 git_reference_free(ref
);
233 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
234 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
235 cl_git_pass(git_remote_prune(origin
, &options
.callbacks
));
237 cl_git_pass(git_reference_list(&refnames
, repo
));
238 cl_assert_equal_i(19, (int)refnames
.count
);
239 git_strarray_dispose(&refnames
);
240 git_remote_free(origin
);
242 cl_git_pass(git_reference_lookup(&ref
, remote_repo
, "refs/heads/packed"));
243 cl_git_pass(git_reference_delete(ref
));
244 git_reference_free(ref
);
246 cl_git_pass(git_repository_config(&config
, repo
));
247 cl_git_pass(git_config_set_bool(config
, "remote.origin.prune", 1));
248 git_config_free(config
);
249 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
250 cl_assert_equal_i(1, git_remote_prune_refs(origin
));
251 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
253 cl_git_pass(git_reference_list(&refnames
, repo
));
254 cl_assert_equal_i(18, (int)refnames
.count
);
255 git_strarray_dispose(&refnames
);
256 git_remote_free(origin
);
258 git_repository_free(repo
);
261 void test_network_fetchlocal__prune_tag(void)
263 git_repository
*repo
;
269 git_signature
*tagger
;
272 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
273 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
274 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
276 options
.callbacks
.transfer_progress
= transfer_cb
;
277 options
.callbacks
.payload
= &callcount
;
279 cl_set_cleanup(&cleanup_local_repo
, "foo");
280 cl_git_pass(git_repository_init(&repo
, "foo", true));
282 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
283 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
284 git_remote_free(origin
);
286 cl_git_pass(git_revparse_single(&obj
, repo
, "origin/master"));
288 cl_git_pass(git_reference_create(&ref
, repo
, "refs/remotes/origin/fake-remote", git_object_id(obj
), 1, NULL
));
289 git_reference_free(ref
);
291 /* create signature */
292 cl_git_pass(git_signature_new(&tagger
, tagger_name
, tagger_email
, 123456789, 60));
295 git_tag_create(&tag_id
, repo
,
296 "some-tag", obj
, tagger
, tagger_message
, 0)
298 git_signature_free(tagger
);
300 cl_git_pass(git_repository_config(&config
, repo
));
301 cl_git_pass(git_config_set_bool(config
, "remote.origin.prune", 1));
302 git_config_free(config
);
303 cl_git_pass(git_remote_lookup(&origin
, repo
, GIT_REMOTE_ORIGIN
));
304 cl_assert_equal_i(1, git_remote_prune_refs(origin
));
305 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
307 assert_ref_exists(repo
, "refs/tags/some-tag");
308 cl_git_fail_with(GIT_ENOTFOUND
, git_reference_lookup(&ref
, repo
, "refs/remotes/origin/fake-remote"));
310 git_object_free(obj
);
311 git_remote_free(origin
);
313 git_repository_free(repo
);
316 void test_network_fetchlocal__partial(void)
318 git_repository
*repo
= cl_git_sandbox_init("partial-testrepo");
321 git_strarray refnames
= {0};
323 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
325 options
.callbacks
.transfer_progress
= transfer_cb
;
326 options
.callbacks
.payload
= &callcount
;
328 cl_git_pass(git_reference_list(&refnames
, repo
));
329 cl_assert_equal_i(1, (int)refnames
.count
);
331 url
= cl_git_fixture_url("testrepo.git");
332 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
333 cl_git_pass(git_remote_fetch(origin
, NULL
, &options
, NULL
));
335 git_strarray_dispose(&refnames
);
337 cl_git_pass(git_reference_list(&refnames
, repo
));
338 cl_assert_equal_i(21, (int)refnames
.count
); /* 18 remote + 1 local */
339 cl_assert(callcount
> 0);
341 git_strarray_dispose(&refnames
);
342 git_remote_free(origin
);
345 static int remote_mirror_cb(git_remote
**out
, git_repository
*repo
,
346 const char *name
, const char *url
, void *payload
)
353 if ((error
= git_remote_create_with_fetchspec(&remote
, repo
, name
, url
, "+refs/*:refs/*")) < 0)
360 void test_network_fetchlocal__clone_into_mirror(void)
362 git_clone_options opts
= GIT_CLONE_OPTIONS_INIT
;
363 git_repository
*repo
;
367 opts
.remote_cb
= remote_mirror_cb
;
368 cl_git_pass(git_clone(&repo
, cl_git_fixture_url("testrepo.git"), "./foo.git", &opts
));
370 cl_git_pass(git_reference_lookup(&ref
, repo
, "HEAD"));
371 cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC
, git_reference_type(ref
));
372 cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(ref
));
374 git_reference_free(ref
);
375 cl_git_pass(git_reference_lookup(&ref
, repo
, "refs/remotes/test/master"));
377 git_reference_free(ref
);
378 git_repository_free(repo
);
379 cl_fixture_cleanup("./foo.git");
382 void test_network_fetchlocal__all_refs(void)
384 git_repository
*repo
;
387 char *allrefs
= "+refs/*:refs/*";
388 git_strarray refspecs
= {
393 cl_git_pass(git_repository_init(&repo
, "./foo.git", true));
394 cl_git_pass(git_remote_create_anonymous(&remote
, repo
, cl_git_fixture_url("testrepo.git")));
395 cl_git_pass(git_remote_fetch(remote
, &refspecs
, NULL
, NULL
));
397 cl_git_pass(git_reference_lookup(&ref
, repo
, "refs/remotes/test/master"));
398 git_reference_free(ref
);
400 cl_git_pass(git_reference_lookup(&ref
, repo
, "refs/tags/test"));
401 git_reference_free(ref
);
403 git_remote_free(remote
);
404 git_repository_free(repo
);
405 cl_fixture_cleanup("./foo.git");
408 void test_network_fetchlocal__multi_remotes(void)
410 git_repository
*repo
= cl_git_sandbox_init("testrepo.git");
411 git_remote
*test
, *test2
;
412 git_strarray refnames
= {0};
413 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
415 options
.callbacks
.transfer_progress
= transfer_cb
;
416 cl_git_pass(git_remote_set_url(repo
, "test", cl_git_fixture_url("testrepo.git")));
417 cl_git_pass(git_remote_lookup(&test
, repo
, "test"));
418 cl_git_pass(git_remote_fetch(test
, NULL
, &options
, NULL
));
420 cl_git_pass(git_reference_list(&refnames
, repo
));
421 cl_assert_equal_i(35, (int)refnames
.count
);
422 git_strarray_dispose(&refnames
);
424 cl_git_pass(git_remote_set_url(repo
, "test_with_pushurl", cl_git_fixture_url("testrepo.git")));
425 cl_git_pass(git_remote_lookup(&test2
, repo
, "test_with_pushurl"));
426 cl_git_pass(git_remote_fetch(test2
, NULL
, &options
, NULL
));
428 cl_git_pass(git_reference_list(&refnames
, repo
));
429 cl_assert_equal_i(48, (int)refnames
.count
);
431 git_strarray_dispose(&refnames
);
432 git_remote_free(test
);
433 git_remote_free(test2
);
436 static int sideband_cb(const char *str
, int len
, void *payload
)
438 int *count
= (int *) payload
;
447 void test_network_fetchlocal__call_progress(void)
449 git_repository
*repo
;
451 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
454 cl_git_pass(git_repository_init(&repo
, "foo.git", true));
455 cl_set_cleanup(cleanup_local_repo
, "foo.git");
457 cl_git_pass(git_remote_create_with_fetchspec(&remote
, repo
, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/heads/*"));
459 options
.callbacks
.sideband_progress
= sideband_cb
;
460 options
.callbacks
.payload
= &callcount
;
462 cl_git_pass(git_remote_fetch(remote
, NULL
, &options
, NULL
));
463 cl_assert(callcount
!= 0);
465 git_remote_free(remote
);
466 git_repository_free(repo
);
469 void test_network_fetchlocal__prune_load_remote_prune_config(void)
471 git_repository
*repo
;
474 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
475 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
477 cl_set_cleanup(&cleanup_local_repo
, "foo");
478 cl_git_pass(git_repository_init(&repo
, "foo", true));
480 cl_git_pass(git_repository_config(&config
, repo
));
481 cl_git_pass(git_config_set_bool(config
, "remote.origin.prune", 1));
483 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
484 cl_assert_equal_i(1, git_remote_prune_refs(origin
));
486 git_config_free(config
);
487 git_remote_free(origin
);
488 git_repository_free(repo
);
491 void test_network_fetchlocal__prune_load_fetch_prune_config(void)
493 git_repository
*repo
;
496 git_repository
*remote_repo
= cl_git_sandbox_init("testrepo.git");
497 const char *url
= cl_git_path_url(git_repository_path(remote_repo
));
499 cl_set_cleanup(&cleanup_local_repo
, "foo");
500 cl_git_pass(git_repository_init(&repo
, "foo", true));
502 cl_git_pass(git_repository_config(&config
, repo
));
503 cl_git_pass(git_config_set_bool(config
, "fetch.prune", 1));
505 cl_git_pass(git_remote_create(&origin
, repo
, GIT_REMOTE_ORIGIN
, url
));
506 cl_assert_equal_i(1, git_remote_prune_refs(origin
));
508 git_config_free(config
);
509 git_remote_free(origin
);
510 git_repository_free(repo
);
513 static int update_tips_error(const char *ref
, const git_oid
*old
, const git_oid
*new, void *data
)
515 int *callcount
= (int *) data
;
526 void test_network_fetchlocal__update_tips_error_is_propagated(void)
528 git_repository
*repo
;
529 git_reference_iterator
*iterator
;
532 git_fetch_options options
= GIT_FETCH_OPTIONS_INIT
;
535 cl_git_pass(git_repository_init(&repo
, "foo.git", true));
536 cl_set_cleanup(cleanup_local_repo
, "foo.git");
538 cl_git_pass(git_remote_create_with_fetchspec(&remote
, repo
, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/remotes/update-tips/*"));
540 options
.callbacks
.update_tips
= update_tips_error
;
541 options
.callbacks
.payload
= &callcount
;
543 cl_git_fail(git_remote_fetch(remote
, NULL
, &options
, NULL
));
544 cl_assert_equal_i(1, callcount
);
546 cl_git_pass(git_reference_iterator_glob_new(&iterator
, repo
, "refs/remotes/update-tips/**/"));
547 cl_assert_equal_i(GIT_ITEROVER
, git_reference_next(&ref
, iterator
));
549 git_reference_iterator_free(iterator
);
550 git_remote_free(remote
);
551 git_repository_free(repo
);