]> git.proxmox.com Git - libgit2.git/blob - tests/revert/workdir.c
Bare naked merge and rebase
[libgit2.git] / tests / revert / workdir.c
1 #include "clar.h"
2 #include "clar_libgit2.h"
3
4 #include "buffer.h"
5 #include "fileops.h"
6 #include "git2/revert.h"
7
8 #include "../merge/merge_helpers.h"
9
10 #define TEST_REPO_PATH "revert"
11
12 static git_repository *repo;
13 static git_index *repo_index;
14
15 // Fixture setup and teardown
16 void test_revert_workdir__initialize(void)
17 {
18 repo = cl_git_sandbox_init(TEST_REPO_PATH);
19 git_repository_index(&repo_index, repo);
20 }
21
22 void test_revert_workdir__cleanup(void)
23 {
24 git_index_free(repo_index);
25 cl_git_sandbox_cleanup();
26 }
27
28 /* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45
29 * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */
30 void test_revert_workdir__automerge(void)
31 {
32 git_commit *head, *commit;
33 git_oid head_oid, revert_oid;
34
35 struct merge_index_entry merge_index_entries[] = {
36 { 0100644, "caf99de3a49827117bb66721010eac461b06a80c", 0, "file1.txt" },
37 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
38 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
39 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
40 };
41
42 git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
43 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
44 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
45
46 git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
47 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
48 cl_git_pass(git_revert(repo, commit, NULL));
49
50 cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
51
52 git_commit_free(commit);
53 git_commit_free(head);
54 }
55
56 /* git revert --no-commit 72333f47d4e83616630ff3b0ffe4c0faebcc3c45 */
57 void test_revert_workdir__conflicts(void)
58 {
59 git_reference *head_ref;
60 git_commit *head, *commit;
61 git_oid revert_oid;
62 git_buf conflicting_buf = GIT_BUF_INIT;
63
64 struct merge_index_entry merge_index_entries[] = {
65 { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 1, "file1.txt" },
66 { 0100644, "4b8fcff56437e60f58e9a6bc630dd242ebf6ea2c", 2, "file1.txt" },
67 { 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 3, "file1.txt" },
68 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
69 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
70 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
71 };
72
73 git_oid_fromstr(&revert_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
74
75 cl_git_pass(git_repository_head(&head_ref, repo));
76 cl_git_pass(git_reference_peel((git_object **)&head, head_ref, GIT_OBJ_COMMIT));
77 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
78
79 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
80 cl_git_pass(git_revert(repo, commit, NULL));
81
82 cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
83
84 cl_git_pass(git_futils_readbuffer(&conflicting_buf,
85 TEST_REPO_PATH "/file1.txt"));
86 cl_assert(strcmp(conflicting_buf.ptr, "!File one!\n" \
87 "!File one!\n" \
88 "File one!\n" \
89 "File one\n" \
90 "File one\n" \
91 "File one\n" \
92 "File one\n" \
93 "File one\n" \
94 "File one\n" \
95 "File one\n" \
96 "<<<<<<< HEAD\n" \
97 "File one!\n" \
98 "!File one!\n" \
99 "!File one!\n" \
100 "!File one!\n" \
101 "=======\n" \
102 "File one\n" \
103 "File one\n" \
104 "File one\n" \
105 "File one\n" \
106 ">>>>>>> parent of 72333f4... automergeable changes\n") == 0);
107
108 git_commit_free(commit);
109 git_commit_free(head);
110 git_reference_free(head_ref);
111 git_buf_free(&conflicting_buf);
112 }
113
114 /* git reset --hard 39467716290f6df775a91cdb9a4eb39295018145
115 * git revert --no-commit ebb03002cee5d66c7732dd06241119fe72ab96a5
116 */
117 void test_revert_workdir__orphan(void)
118 {
119 git_commit *head, *commit;
120 git_oid head_oid, revert_oid;
121
122 struct merge_index_entry merge_index_entries[] = {
123 { 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" },
124 };
125
126 git_oid_fromstr(&head_oid, "39467716290f6df775a91cdb9a4eb39295018145");
127 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
128 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
129
130 git_oid_fromstr(&revert_oid, "ebb03002cee5d66c7732dd06241119fe72ab96a5");
131 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
132 cl_git_pass(git_revert(repo, commit, NULL));
133
134 cl_assert(merge_test_index(repo_index, merge_index_entries, 1));
135
136 git_commit_free(commit);
137 git_commit_free(head);
138 }
139
140 /* git reset --hard 72333f47d4e83616630ff3b0ffe4c0faebcc3c45
141 * git revert --no-commit d1d403d22cbe24592d725f442835cf46fe60c8ac */
142 void test_revert_workdir__conflict_use_ours(void)
143 {
144 git_commit *head, *commit;
145 git_oid head_oid, revert_oid;
146 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
147
148 opts.merge_tree_opts.automerge_flags = GIT_MERGE_AUTOMERGE_NONE;
149 opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
150
151 struct merge_index_entry merge_index_entries[] = {
152 { 0100644, "3a3ef367eaf3fe79effbfb0a56b269c04c2b59fe", 1, "file1.txt" },
153 { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 2, "file1.txt" },
154 { 0100644, "747726e021bc5f44b86de60e3032fd6f9f1b8383", 3, "file1.txt" },
155 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
156 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
157 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
158 };
159
160 struct merge_index_entry merge_filesystem_entries[] = {
161 { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 0, "file1.txt" },
162 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
163 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
164 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
165 };
166
167 git_oid_fromstr(&head_oid, "72333f47d4e83616630ff3b0ffe4c0faebcc3c45");
168 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
169 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
170
171 git_oid_fromstr(&revert_oid, "d1d403d22cbe24592d725f442835cf46fe60c8ac");
172 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
173 cl_git_pass(git_revert(repo, commit, &opts));
174
175 cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
176 cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 4));
177
178 git_commit_free(commit);
179 git_commit_free(head);
180 }
181
182 /* git reset --hard cef56612d71a6af8d8015691e4865f7fece905b5
183 * git revert --no-commit 55568c8de5322ff9a95d72747a239cdb64a19965
184 */
185 void test_revert_workdir__rename_1_of_2(void)
186 {
187 git_commit *head, *commit;
188 git_oid head_oid, revert_oid;
189 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
190
191 opts.merge_tree_opts.flags |= GIT_MERGE_TREE_FIND_RENAMES;
192 opts.merge_tree_opts.rename_threshold = 50;
193
194 struct merge_index_entry merge_index_entries[] = {
195 { 0100644, "747726e021bc5f44b86de60e3032fd6f9f1b8383", 0, "file1.txt" },
196 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
197 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
198 { 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 3, "file4.txt" },
199 { 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 1, "file5.txt" },
200 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 2, "file6.txt" },
201 };
202
203 git_oid_fromstr(&head_oid, "cef56612d71a6af8d8015691e4865f7fece905b5");
204 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
205 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
206
207 git_oid_fromstr(&revert_oid, "55568c8de5322ff9a95d72747a239cdb64a19965");
208 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
209 cl_git_pass(git_revert(repo, commit, &opts));
210
211 cl_assert(merge_test_index(repo_index, merge_index_entries, 6));
212
213 git_commit_free(commit);
214 git_commit_free(head);
215 }
216
217 /* git reset --hard 55568c8de5322ff9a95d72747a239cdb64a19965
218 * git revert --no-commit HEAD~1 */
219 void test_revert_workdir__rename(void)
220 {
221 git_commit *head, *commit;
222 git_oid head_oid, revert_oid;
223 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
224
225 opts.merge_tree_opts.flags |= GIT_MERGE_TREE_FIND_RENAMES;
226 opts.merge_tree_opts.rename_threshold = 50;
227
228 struct merge_index_entry merge_index_entries[] = {
229 { 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 1, "file4.txt" },
230 { 0100644, "55acf326a69f0aab7a974ec53ffa55a50bcac14e", 2, "file5.txt" },
231 };
232
233 struct merge_name_entry merge_name_entries[] = {
234 { "file4.txt", "file5.txt", "" },
235 };
236
237 git_oid_fromstr(&head_oid, "55568c8de5322ff9a95d72747a239cdb64a19965");
238 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
239 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
240
241 git_oid_fromstr(&revert_oid, "0aa8c7e40d342fff78d60b29a4ba8e993ed79c51");
242 cl_git_pass(git_commit_lookup(&commit, repo, &revert_oid));
243 cl_git_pass(git_revert(repo, commit, &opts));
244
245 cl_assert(merge_test_index(repo_index, merge_index_entries, 2));
246 cl_assert(merge_test_names(repo_index, merge_name_entries, 1));
247
248 git_commit_free(commit);
249 git_commit_free(head);
250 }
251
252 /* git revert --no-commit HEAD */
253 void test_revert_workdir__head(void)
254 {
255 git_reference *head;
256 git_commit *commit;
257
258 struct merge_index_entry merge_index_entries[] = {
259 { 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 0, "file1.txt" },
260 { 0100644, "0ab09ea6d4c3634bdf6c221626d8b6f7dd890767", 0, "file2.txt" },
261 { 0100644, "f4e107c230d08a60fb419d19869f1f282b272d9c", 0, "file3.txt" },
262 { 0100644, "0f5bfcf58c558d865da6be0281d7795993646cee", 0, "file6.txt" },
263 };
264
265 /* HEAD is 2d440f2b3147d3dc7ad1085813478d6d869d5a4d */
266 cl_git_pass(git_repository_head(&head, repo));
267 cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
268 cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD));
269 cl_git_pass(git_revert(repo, commit, NULL));
270
271 cl_assert(merge_test_index(repo_index, merge_index_entries, 4));
272 cl_assert(merge_test_workdir(repo, merge_index_entries, 4));
273
274 git_reference_free(head);
275 git_commit_free(commit);
276 }
277
278 void test_revert_workdir__nonmerge_fails_mainline_specified(void)
279 {
280 git_reference *head;
281 git_commit *commit;
282 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
283
284 cl_git_pass(git_repository_head(&head, repo));
285 cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
286
287 opts.mainline = 1;
288 cl_must_fail(git_revert(repo, commit, &opts));
289 cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
290 cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD"));
291
292 git_reference_free(head);
293 git_commit_free(commit);
294 }
295
296 /* git reset --hard 5acdc74af27172ec491d213ee36cea7eb9ef2579
297 * git revert HEAD */
298 void test_revert_workdir__merge_fails_without_mainline_specified(void)
299 {
300 git_commit *head;
301 git_oid head_oid;
302
303 git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
304 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
305 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
306
307 cl_must_fail(git_revert(repo, head, NULL));
308 cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
309 cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD"));
310
311 git_commit_free(head);
312 }
313
314 /* git reset --hard 5acdc74af27172ec491d213ee36cea7eb9ef2579
315 * git revert HEAD -m1 --no-commit */
316 void test_revert_workdir__merge_first_parent(void)
317 {
318 git_commit *head;
319 git_oid head_oid;
320 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
321
322 opts.mainline = 1;
323
324 struct merge_index_entry merge_index_entries[] = {
325 { 0100644, "296a6d3be1dff05c5d1f631d2459389fa7b619eb", 0, "file-mainline.txt" },
326 { 0100644, "0cdb66192ee192f70f891f05a47636057420e871", 0, "file1.txt" },
327 { 0100644, "73ec36fa120f8066963a0bc9105bb273dbd903d7", 0, "file2.txt" },
328 };
329
330 git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
331 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
332 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
333
334 cl_git_pass(git_revert(repo, head, &opts));
335
336 cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
337
338 git_commit_free(head);
339 }
340
341 void test_revert_workdir__merge_second_parent(void)
342 {
343 git_commit *head;
344 git_oid head_oid;
345 git_revert_opts opts = GIT_REVERT_OPTS_INIT;
346
347 opts.mainline = 2;
348
349 struct merge_index_entry merge_index_entries[] = {
350 { 0100644, "33c6fd981c49a2abf2971482089350bfc5cda8ea", 0, "file-branch.txt" },
351 { 0100644, "0cdb66192ee192f70f891f05a47636057420e871", 0, "file1.txt" },
352 { 0100644, "73ec36fa120f8066963a0bc9105bb273dbd903d7", 0, "file2.txt" },
353 };
354
355 git_oid_fromstr(&head_oid, "5acdc74af27172ec491d213ee36cea7eb9ef2579");
356 cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
357 cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD));
358
359 cl_git_pass(git_revert(repo, head, &opts));
360
361 cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
362
363 git_commit_free(head);
364 }