1 #include "clar_libgit2.h"
2 #include "git2/repository.h"
3 #include "git2/merge.h"
4 #include "git2/sys/index.h"
6 #include "../merge_helpers.h"
10 static git_repository
*repo
;
11 static git_index
*repo_index
;
13 #define TEST_REPO_PATH "merge-resolve"
14 #define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
17 /* Fixture setup and teardown */
18 void test_merge_workdir_trivial__initialize(void)
20 repo
= cl_git_sandbox_init(TEST_REPO_PATH
);
21 git_repository_index(&repo_index
, repo
);
24 void test_merge_workdir_trivial__cleanup(void)
26 git_index_free(repo_index
);
27 cl_git_sandbox_cleanup();
31 static int merge_trivial(const char *ours
, const char *theirs
)
33 git_buf branch_buf
= GIT_BUF_INIT
;
34 git_checkout_options checkout_opts
= GIT_CHECKOUT_OPTIONS_INIT
;
35 git_reference
*our_ref
, *their_ref
;
36 git_annotated_commit
*their_heads
[1];
38 checkout_opts
.checkout_strategy
= GIT_CHECKOUT_FORCE
;
40 git_buf_printf(&branch_buf
, "%s%s", GIT_REFS_HEADS_DIR
, ours
);
41 cl_git_pass(git_reference_symbolic_create(&our_ref
, repo
, "HEAD", branch_buf
.ptr
, 1, NULL
));
43 cl_git_pass(git_checkout_head(repo
, &checkout_opts
));
45 git_buf_clear(&branch_buf
);
46 git_buf_printf(&branch_buf
, "%s%s", GIT_REFS_HEADS_DIR
, theirs
);
47 cl_git_pass(git_reference_lookup(&their_ref
, repo
, branch_buf
.ptr
));
48 cl_git_pass(git_annotated_commit_from_ref(&their_heads
[0], repo
, their_ref
));
50 cl_git_pass(git_merge(repo
, (const git_annotated_commit
**)their_heads
, 1, NULL
, NULL
));
52 git_buf_dispose(&branch_buf
);
53 git_reference_free(our_ref
);
54 git_reference_free(their_ref
);
55 git_annotated_commit_free(their_heads
[0]);
60 static size_t merge_trivial_conflict_entrycount(void)
62 const git_index_entry
*entry
;
66 for (i
= 0; i
< git_index_entrycount(repo_index
); i
++) {
67 cl_assert(entry
= git_index_get_byindex(repo_index
, i
));
69 if (git_index_entry_is_conflict(entry
))
76 /* 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote */
77 void test_merge_workdir_trivial__2alt(void)
79 const git_index_entry
*entry
;
81 cl_git_pass(merge_trivial("trivial-2alt", "trivial-2alt-branch"));
83 cl_assert(entry
= git_index_get_bypath(repo_index
, "new-in-branch.txt", 0));
84 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
85 cl_assert(merge_trivial_conflict_entrycount() == 0);
88 /* 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head */
89 void test_merge_workdir_trivial__3alt(void)
91 const git_index_entry
*entry
;
93 cl_git_pass(merge_trivial("trivial-3alt", "trivial-3alt-branch"));
95 cl_assert(entry
= git_index_get_bypath(repo_index
, "new-in-3alt.txt", 0));
96 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
97 cl_assert(merge_trivial_conflict_entrycount() == 0);
100 /* 4: ancest:(empty)^, head:head, remote:remote = result:no merge */
101 void test_merge_workdir_trivial__4(void)
103 const git_index_entry
*entry
;
105 cl_git_pass(merge_trivial("trivial-4", "trivial-4-branch"));
107 cl_assert((entry
= git_index_get_bypath(repo_index
, "new-and-different.txt", 0)) == NULL
);
108 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
110 cl_assert(merge_trivial_conflict_entrycount() == 2);
111 cl_assert(entry
= git_index_get_bypath(repo_index
, "new-and-different.txt", 2));
112 cl_assert(entry
= git_index_get_bypath(repo_index
, "new-and-different.txt", 3));
115 /* 5ALT: ancest:*, head:head, remote:head = result:head */
116 void test_merge_workdir_trivial__5alt_1(void)
118 const git_index_entry
*entry
;
120 cl_git_pass(merge_trivial("trivial-5alt-1", "trivial-5alt-1-branch"));
122 cl_assert(entry
= git_index_get_bypath(repo_index
, "new-and-same.txt", 0));
123 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
124 cl_assert(merge_trivial_conflict_entrycount() == 0);
127 /* 5ALT: ancest:*, head:head, remote:head = result:head */
128 void test_merge_workdir_trivial__5alt_2(void)
130 const git_index_entry
*entry
;
132 cl_git_pass(merge_trivial("trivial-5alt-2", "trivial-5alt-2-branch"));
134 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-to-same.txt", 0));
135 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
136 cl_assert(merge_trivial_conflict_entrycount() == 0);
139 /* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */
140 void test_merge_workdir_trivial__6(void)
142 const git_index_entry
*entry
;
143 const git_index_reuc_entry
*reuc
;
145 cl_git_pass(merge_trivial("trivial-6", "trivial-6-branch"));
147 cl_assert((entry
= git_index_get_bypath(repo_index
, "removed-in-both.txt", 0)) == NULL
);
148 cl_assert(git_index_reuc_entrycount(repo_index
) == 1);
149 cl_assert(reuc
= git_index_reuc_get_bypath(repo_index
, "removed-in-both.txt"));
151 cl_assert(merge_trivial_conflict_entrycount() == 0);
154 /* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */
155 void test_merge_workdir_trivial__8(void)
157 const git_index_entry
*entry
;
158 const git_index_reuc_entry
*reuc
;
160 cl_git_pass(merge_trivial("trivial-8", "trivial-8-branch"));
162 cl_assert((entry
= git_index_get_bypath(repo_index
, "removed-in-8.txt", 0)) == NULL
);
164 cl_assert(git_index_reuc_entrycount(repo_index
) == 1);
165 cl_assert(reuc
= git_index_reuc_get_bypath(repo_index
, "removed-in-8.txt"));
167 cl_assert(merge_trivial_conflict_entrycount() == 0);
170 /* 7: ancest:ancest+, head:(empty), remote:remote = result:no merge */
171 void test_merge_workdir_trivial__7(void)
173 const git_index_entry
*entry
;
175 cl_git_pass(merge_trivial("trivial-7", "trivial-7-branch"));
177 cl_assert((entry
= git_index_get_bypath(repo_index
, "removed-in-7.txt", 0)) == NULL
);
178 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
180 cl_assert(merge_trivial_conflict_entrycount() == 2);
181 cl_assert(entry
= git_index_get_bypath(repo_index
, "removed-in-7.txt", 1));
182 cl_assert(entry
= git_index_get_bypath(repo_index
, "removed-in-7.txt", 3));
185 /* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */
186 void test_merge_workdir_trivial__10(void)
188 const git_index_entry
*entry
;
189 const git_index_reuc_entry
*reuc
;
191 cl_git_pass(merge_trivial("trivial-10", "trivial-10-branch"));
193 cl_assert((entry
= git_index_get_bypath(repo_index
, "removed-in-10-branch.txt", 0)) == NULL
);
195 cl_assert(git_index_reuc_entrycount(repo_index
) == 1);
196 cl_assert(reuc
= git_index_reuc_get_bypath(repo_index
, "removed-in-10-branch.txt"));
198 cl_assert(merge_trivial_conflict_entrycount() == 0);
201 /* 9: ancest:ancest+, head:head, remote:(empty) = result:no merge */
202 void test_merge_workdir_trivial__9(void)
204 const git_index_entry
*entry
;
206 cl_git_pass(merge_trivial("trivial-9", "trivial-9-branch"));
208 cl_assert((entry
= git_index_get_bypath(repo_index
, "removed-in-9-branch.txt", 0)) == NULL
);
209 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
211 cl_assert(merge_trivial_conflict_entrycount() == 2);
212 cl_assert(entry
= git_index_get_bypath(repo_index
, "removed-in-9-branch.txt", 1));
213 cl_assert(entry
= git_index_get_bypath(repo_index
, "removed-in-9-branch.txt", 2));
216 /* 13: ancest:ancest+, head:head, remote:ancest = result:head */
217 void test_merge_workdir_trivial__13(void)
219 const git_index_entry
*entry
;
220 git_oid expected_oid
;
222 cl_git_pass(merge_trivial("trivial-13", "trivial-13-branch"));
224 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-in-13.txt", 0));
225 cl_git_pass(git_oid_fromstr(&expected_oid
, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b"));
226 cl_assert(git_oid_cmp(&entry
->id
, &expected_oid
) == 0);
228 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
229 cl_assert(merge_trivial_conflict_entrycount() == 0);
232 /* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */
233 void test_merge_workdir_trivial__14(void)
235 const git_index_entry
*entry
;
236 git_oid expected_oid
;
238 cl_git_pass(merge_trivial("trivial-14", "trivial-14-branch"));
240 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-in-14-branch.txt", 0));
241 cl_git_pass(git_oid_fromstr(&expected_oid
, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9"));
242 cl_assert(git_oid_cmp(&entry
->id
, &expected_oid
) == 0);
244 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
245 cl_assert(merge_trivial_conflict_entrycount() == 0);
248 /* 11: ancest:ancest+, head:head, remote:remote = result:no merge */
249 void test_merge_workdir_trivial__11(void)
251 const git_index_entry
*entry
;
253 cl_git_pass(merge_trivial("trivial-11", "trivial-11-branch"));
255 cl_assert((entry
= git_index_get_bypath(repo_index
, "modified-in-both.txt", 0)) == NULL
);
256 cl_assert(git_index_reuc_entrycount(repo_index
) == 0);
258 cl_assert(merge_trivial_conflict_entrycount() == 3);
259 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-in-both.txt", 1));
260 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-in-both.txt", 2));
261 cl_assert(entry
= git_index_get_bypath(repo_index
, "modified-in-both.txt", 3));