]>
git.proxmox.com Git - libgit2.git/blob - tests/remote/fetch.c
7e825ca16ca2d35d0cbed7c90cff55a71e63cb04
1 #include "../clar_libgit2.h"
4 #include "repository.h"
6 static git_repository
*repo1
;
7 static git_repository
*repo2
;
8 static char* repo1_path
;
9 static char* repo2_path
;
11 static const char *REPO1_REFNAME
= "refs/heads/main";
12 static const char *REPO2_REFNAME
= "refs/remotes/repo1/main";
13 static char *FORCE_FETCHSPEC
= "+refs/heads/main:refs/remotes/repo1/main";
14 static char *NON_FORCE_FETCHSPEC
= "refs/heads/main:refs/remotes/repo1/main";
16 void test_remote_fetch__initialize(void) {
18 git_buf repo1_path_buf
= GIT_BUF_INIT
;
19 git_buf repo2_path_buf
= GIT_BUF_INIT
;
20 const char *sandbox
= clar_sandbox_path();
22 cl_git_pass(git_buf_joinpath(&repo1_path_buf
, sandbox
, "fetchtest_repo1"));
23 repo1_path
= git_buf_detach(&repo1_path_buf
);
24 cl_git_pass(git_repository_init(&repo1
, repo1_path
, true));
26 cl_git_pass(git_buf_joinpath(&repo2_path_buf
, sandbox
, "fetchtest_repo2"));
27 repo2_path
= git_buf_detach(&repo2_path_buf
);
28 cl_git_pass(git_repository_init(&repo2
, repo2_path
, true));
30 cl_git_pass(git_repository_config(&c
, repo1
));
31 cl_git_pass(git_config_set_string(c
, "user.email", "some@email"));
32 cl_git_pass(git_config_set_string(c
, "user.name", "some@name"));
34 git_buf_dispose(&repo1_path_buf
);
35 git_buf_dispose(&repo2_path_buf
);
38 void test_remote_fetch__cleanup(void) {
39 git_repository_free(repo1
);
40 git_repository_free(repo2
);
42 cl_git_pass(git_futils_rmdir_r(repo1_path
, NULL
, GIT_RMDIR_REMOVE_FILES
));
45 cl_git_pass(git_futils_rmdir_r(repo2_path
, NULL
, GIT_RMDIR_REMOVE_FILES
));
51 * This checks that the '+' flag on fetchspecs is respected. We create a
52 * repository that has a reference to two commits, one a child of the other.
53 * We fetch this repository into a second repository. Then we reset the
54 * reference in the first repository and run the fetch again. If the '+' flag
55 * is used then the reference in the second repository will change, but if it
56 * is not then it should stay the same.
58 * @param commit1id A pointer to an OID which will be populated with the first
60 * @param commit2id A pointer to an OID which will be populated with the second
61 * commit, which is a descendant of the first.
62 * @param force Whether to use a spec with '+' prefixed to force the refs
65 void do_time_travelling_fetch(git_oid
*commit1id
, git_oid
*commit2id
,
67 char *refspec_strs
= {
68 force
? FORCE_FETCHSPEC
: NON_FORCE_FETCHSPEC
,
70 git_strarray refspecs
= {
72 .strings
= &refspec_strs
,
75 /* create two commits in repo 1 and a reference to them */
77 git_oid empty_tree_id
;
81 cl_git_pass(git_treebuilder_new(&tb
, repo1
, NULL
));
82 cl_git_pass(git_treebuilder_write(&empty_tree_id
, tb
));
83 cl_git_pass(git_tree_lookup(&empty_tree
, repo1
, &empty_tree_id
));
84 cl_git_pass(git_signature_default(&sig
, repo1
));
85 cl_git_pass(git_commit_create(commit1id
, repo1
, REPO1_REFNAME
, sig
,
86 sig
, NULL
, "one", empty_tree
, 0, NULL
));
87 cl_git_pass(git_commit_create_v(commit2id
, repo1
, REPO1_REFNAME
, sig
,
88 sig
, NULL
, "two", empty_tree
, 1, commit1id
));
90 git_tree_free(empty_tree
);
91 git_signature_free(sig
);
92 git_treebuilder_free(tb
);
95 /* fetch the reference via the remote */
99 cl_git_pass(git_remote_create_anonymous(&remote
, repo2
,
100 git_repository_path(repo1
)));
101 cl_git_pass(git_remote_fetch(remote
, &refspecs
, NULL
, "some message"));
103 git_remote_free(remote
);
106 /* assert that repo2 references the second commit */
108 const git_oid
*target
;
110 cl_git_pass(git_reference_lookup(&ref
, repo2
, REPO2_REFNAME
));
111 target
= git_reference_target(ref
);
112 cl_assert_equal_b(git_oid_cmp(target
, commit2id
), 0);
113 git_reference_free(ref
);
116 /* set the reference in repo1 to point to the older commit */
120 cl_git_pass(git_reference_lookup(&ref
, repo1
, REPO1_REFNAME
));
121 cl_git_pass(git_reference_set_target(&ref2
, ref
, commit1id
,
123 git_reference_free(ref
);
124 git_reference_free(ref2
);
127 /* fetch the reference again */
131 cl_git_pass(git_remote_create_anonymous(&remote
, repo2
,
132 git_repository_path(repo1
)));
133 cl_git_pass(git_remote_fetch(remote
, &refspecs
, NULL
, "some message"));
135 git_remote_free(remote
);
139 void test_remote_fetch__dont_update_refs_if_not_descendant_and_not_force(void) {
140 const git_oid
*target
;
145 do_time_travelling_fetch(&commit1id
, &commit2id
, false);
147 /* assert that the reference in repo2 has not changed */
148 cl_git_pass(git_reference_lookup(&ref
, repo2
, REPO2_REFNAME
));
149 target
= git_reference_target(ref
);
150 cl_assert_equal_b(git_oid_cmp(target
, &commit2id
), 0);
152 git_reference_free(ref
);
155 void test_remote_fetch__do_update_refs_if_not_descendant_and_force(void) {
156 const git_oid
*target
;
161 do_time_travelling_fetch(&commit1id
, &commit2id
, true);
163 /* assert that the reference in repo2 has changed */
164 cl_git_pass(git_reference_lookup(&ref
, repo2
, REPO2_REFNAME
));
165 target
= git_reference_target(ref
);
166 cl_assert_equal_b(git_oid_cmp(target
, &commit1id
), 0);
168 git_reference_free(ref
);