1 #include "clar_libgit2.h"
2 #include "git2/checkout.h"
3 #include "git2/rebase.h"
9 static git_repository
*repo
;
10 static git_signature
*signature
;
12 static void set_core_autocrlf_to(git_repository
*repo
, bool value
)
16 cl_git_pass(git_repository_config(&cfg
, repo
));
17 cl_git_pass(git_config_set_bool(cfg
, "core.autocrlf", value
));
22 /* Fixture setup and teardown */
23 void test_rebase_merge__initialize(void)
25 repo
= cl_git_sandbox_init("rebase");
26 cl_git_pass(git_signature_new(&signature
,
27 "Rebaser", "rebaser@rebaser.rb", 1405694510, 0));
29 set_core_autocrlf_to(repo
, false);
32 void test_rebase_merge__cleanup(void)
34 git_signature_free(signature
);
35 cl_git_sandbox_cleanup();
38 void test_rebase_merge__next(void)
41 git_reference
*branch_ref
, *upstream_ref
;
42 git_annotated_commit
*branch_head
, *upstream_head
;
43 git_rebase_operation
*rebase_operation
;
44 git_status_list
*status_list
;
45 const git_status_entry
*status_entry
;
46 git_oid pick_id
, file1_id
;
47 git_oid master_id
, beef_id
;
49 git_oid_fromstr(&master_id
, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
50 git_oid_fromstr(&beef_id
, "b146bd7608eac53d9bf9e1a6963543588b555c64");
52 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
53 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
55 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
56 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
58 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
60 cl_assert_equal_s("refs/heads/beef", git_rebase_orig_head_name(rebase
));
61 cl_assert_equal_oid(&beef_id
, git_rebase_orig_head_id(rebase
));
63 cl_assert_equal_s("master", git_rebase_onto_name(rebase
));
64 cl_assert_equal_oid(&master_id
, git_rebase_onto_id(rebase
));
66 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
68 git_oid_fromstr(&pick_id
, "da9c51a23d02d931a486f45ad18cda05cf5d2b94");
70 cl_assert_equal_i(GIT_REBASE_OPERATION_PICK
, rebase_operation
->type
);
71 cl_assert_equal_oid(&pick_id
, &rebase_operation
->id
);
72 cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/current");
73 cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/msgnum");
75 cl_git_pass(git_status_list_new(&status_list
, repo
, NULL
));
76 cl_assert_equal_i(1, git_status_list_entrycount(status_list
));
77 cl_assert(status_entry
= git_status_byindex(status_list
, 0));
79 cl_assert_equal_s("beef.txt", status_entry
->head_to_index
->new_file
.path
);
81 git_oid_fromstr(&file1_id
, "8d95ea62e621f1d38d230d9e7d206e41096d76af");
82 cl_assert_equal_oid(&file1_id
, &status_entry
->head_to_index
->new_file
.id
);
84 git_status_list_free(status_list
);
85 git_annotated_commit_free(branch_head
);
86 git_annotated_commit_free(upstream_head
);
87 git_reference_free(branch_ref
);
88 git_reference_free(upstream_ref
);
89 git_rebase_free(rebase
);
92 void test_rebase_merge__next_with_conflicts(void)
95 git_reference
*branch_ref
, *upstream_ref
;
96 git_annotated_commit
*branch_head
, *upstream_head
;
97 git_rebase_operation
*rebase_operation
;
98 git_status_list
*status_list
;
99 const git_status_entry
*status_entry
;
100 git_oid pick_id
, commit_id
;
102 const char *expected_merge
=
106 "TAKE FOUR LARGE BUNCHES of asparagus, scrape it nicely, cut off one inch\n"
107 "OF THE TOPS, and lay them in water, chop the stalks and put them on the\n"
108 "FIRE WITH A PIECE OF BACON, a large onion cut up, and pepper and salt;\n"
109 "ADD TWO QUARTS OF WATER, boil them till the stalks are quite soft, then\n"
110 "PULP THEM THROUGH A SIEVE, and strain the water to it, which must be put\n"
112 "Take four large bunches of asparagus, scrape it nicely, CUT OFF ONE INCH\n"
113 "of the tops, and lay them in water, chop the stalks and PUT THEM ON THE\n"
114 "fire with a piece of bacon, a large onion cut up, and pepper and salt;\n"
115 "add two quarts of water, boil them till the stalks are quite soft, then\n"
116 "pulp them through a sieve, and strain the water to it, which must be put\n"
117 ">>>>>>> Conflicting modification 1 to asparagus\n"
118 "back in the pot; put into it a chicken cut up, with the tops of\n"
119 "asparagus which had been laid by, boil it until these last articles are\n"
120 "sufficiently done, thicken with flour, butter and milk, and serve it up.\n";
122 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/asparagus"));
123 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
125 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
126 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
128 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
130 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
132 git_oid_fromstr(&pick_id
, "33f915f9e4dbd9f4b24430e48731a59b45b15500");
134 cl_assert_equal_i(GIT_REBASE_OPERATION_PICK
, rebase_operation
->type
);
135 cl_assert_equal_oid(&pick_id
, &rebase_operation
->id
);
136 cl_assert_equal_file("33f915f9e4dbd9f4b24430e48731a59b45b15500\n", 41, "rebase/.git/rebase-merge/current");
137 cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/msgnum");
139 cl_git_pass(git_status_list_new(&status_list
, repo
, NULL
));
140 cl_assert_equal_i(1, git_status_list_entrycount(status_list
));
141 cl_assert(status_entry
= git_status_byindex(status_list
, 0));
143 cl_assert_equal_s("asparagus.txt", status_entry
->head_to_index
->new_file
.path
);
145 cl_assert_equal_file(expected_merge
, strlen(expected_merge
), "rebase/asparagus.txt");
147 cl_git_fail_with(GIT_EUNMERGED
, git_rebase_commit(&commit_id
, rebase
, NULL
, signature
, NULL
, NULL
));
149 git_status_list_free(status_list
);
150 git_annotated_commit_free(branch_head
);
151 git_annotated_commit_free(upstream_head
);
152 git_reference_free(branch_ref
);
153 git_reference_free(upstream_ref
);
154 git_rebase_free(rebase
);
157 void test_rebase_merge__next_stops_with_iterover(void)
160 git_reference
*branch_ref
, *upstream_ref
;
161 git_annotated_commit
*branch_head
, *upstream_head
;
162 git_rebase_operation
*rebase_operation
;
166 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
167 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
169 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
170 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
172 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
174 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
175 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
178 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
179 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
182 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
183 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
186 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
187 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
190 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
191 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
194 cl_git_fail(error
= git_rebase_next(&rebase_operation
, rebase
));
195 cl_assert_equal_i(GIT_ITEROVER
, error
);
197 cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
198 cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/msgnum");
200 git_annotated_commit_free(branch_head
);
201 git_annotated_commit_free(upstream_head
);
202 git_reference_free(branch_ref
);
203 git_reference_free(upstream_ref
);
204 git_rebase_free(rebase
);
207 void test_rebase_merge__commit(void)
210 git_reference
*branch_ref
, *upstream_ref
;
211 git_annotated_commit
*branch_head
, *upstream_head
;
212 git_rebase_operation
*rebase_operation
;
213 git_oid commit_id
, tree_id
, parent_id
;
214 git_signature
*author
;
217 const git_reflog_entry
*reflog_entry
;
219 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
220 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
222 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
223 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
225 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
227 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
228 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
231 cl_git_pass(git_commit_lookup(&commit
, repo
, &commit_id
));
233 git_oid_fromstr(&parent_id
, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
234 cl_assert_equal_i(1, git_commit_parentcount(commit
));
235 cl_assert_equal_oid(&parent_id
, git_commit_parent_id(commit
, 0));
237 git_oid_fromstr(&tree_id
, "4461379789c777d2a6c1f2ee0e9d6c86731b9992");
238 cl_assert_equal_oid(&tree_id
, git_commit_tree_id(commit
));
240 cl_assert_equal_s(NULL
, git_commit_message_encoding(commit
));
241 cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit
));
243 cl_git_pass(git_signature_new(&author
,
244 "Edward Thomson", "ethomson@edwardthomson.com", 1405621769, 0-(4*60)));
245 cl_assert(git_signature__equal(author
, git_commit_author(commit
)));
247 cl_assert(git_signature__equal(signature
, git_commit_committer(commit
)));
249 /* Make sure the reflogs are updated appropriately */
250 cl_git_pass(git_reflog_read(&reflog
, repo
, "HEAD"));
251 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
252 cl_assert_equal_oid(&parent_id
, git_reflog_entry_id_old(reflog_entry
));
253 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
254 cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry
));
256 git_reflog_free(reflog
);
257 git_signature_free(author
);
258 git_commit_free(commit
);
259 git_annotated_commit_free(branch_head
);
260 git_annotated_commit_free(upstream_head
);
261 git_reference_free(branch_ref
);
262 git_reference_free(upstream_ref
);
263 git_rebase_free(rebase
);
266 void test_rebase_merge__commit_with_id(void)
269 git_oid branch_id
, upstream_id
;
270 git_annotated_commit
*branch_head
, *upstream_head
;
271 git_rebase_operation
*rebase_operation
;
272 git_oid commit_id
, tree_id
, parent_id
;
273 git_signature
*author
;
276 const git_reflog_entry
*reflog_entry
;
278 cl_git_pass(git_oid_fromstr(&branch_id
, "b146bd7608eac53d9bf9e1a6963543588b555c64"));
279 cl_git_pass(git_oid_fromstr(&upstream_id
, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"));
281 cl_git_pass(git_annotated_commit_lookup(&branch_head
, repo
, &branch_id
));
282 cl_git_pass(git_annotated_commit_lookup(&upstream_head
, repo
, &upstream_id
));
284 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
286 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
287 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
290 cl_git_pass(git_commit_lookup(&commit
, repo
, &commit_id
));
292 git_oid_fromstr(&parent_id
, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
293 cl_assert_equal_i(1, git_commit_parentcount(commit
));
294 cl_assert_equal_oid(&parent_id
, git_commit_parent_id(commit
, 0));
296 git_oid_fromstr(&tree_id
, "4461379789c777d2a6c1f2ee0e9d6c86731b9992");
297 cl_assert_equal_oid(&tree_id
, git_commit_tree_id(commit
));
299 cl_assert_equal_s(NULL
, git_commit_message_encoding(commit
));
300 cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit
));
302 cl_git_pass(git_signature_new(&author
,
303 "Edward Thomson", "ethomson@edwardthomson.com", 1405621769, 0-(4*60)));
304 cl_assert(git_signature__equal(author
, git_commit_author(commit
)));
306 cl_assert(git_signature__equal(signature
, git_commit_committer(commit
)));
308 /* Make sure the reflogs are updated appropriately */
309 cl_git_pass(git_reflog_read(&reflog
, repo
, "HEAD"));
310 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
311 cl_assert_equal_oid(&parent_id
, git_reflog_entry_id_old(reflog_entry
));
312 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
313 cl_assert_equal_s("rebase: Modification 1 to beef", git_reflog_entry_message(reflog_entry
));
315 git_reflog_free(reflog
);
316 git_signature_free(author
);
317 git_commit_free(commit
);
318 git_annotated_commit_free(branch_head
);
319 git_annotated_commit_free(upstream_head
);
320 git_rebase_free(rebase
);
323 void test_rebase_merge__blocked_when_dirty(void)
326 git_reference
*branch_ref
, *upstream_ref
;
327 git_annotated_commit
*branch_head
, *upstream_head
;
328 git_rebase_operation
*rebase_operation
;
331 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
332 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
334 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
335 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
337 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
339 /* Allow untracked files */
340 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
341 cl_git_mkfile("rebase/untracked_file.txt", "This is untracked\n");
342 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
345 /* Do not allow unstaged */
346 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
347 cl_git_mkfile("rebase/veal.txt", "This is an unstaged change\n");
348 cl_git_fail_with(GIT_EUNMERGED
, git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
351 git_annotated_commit_free(branch_head
);
352 git_annotated_commit_free(upstream_head
);
353 git_reference_free(branch_ref
);
354 git_reference_free(upstream_ref
);
355 git_rebase_free(rebase
);
358 void test_rebase_merge__commit_updates_rewritten(void)
361 git_reference
*branch_ref
, *upstream_ref
;
362 git_annotated_commit
*branch_head
, *upstream_head
;
363 git_rebase_operation
*rebase_operation
;
366 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
367 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
369 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
370 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
372 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
374 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
375 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
378 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
379 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
382 cl_assert_equal_file(
383 "da9c51a23d02d931a486f45ad18cda05cf5d2b94 776e4c48922799f903f03f5f6e51da8b01e4cce0\n"
384 "8d1f13f93c4995760ac07d129246ac1ff64c0be9 ba1f9b4fd5cf8151f7818be2111cc0869f1eb95a\n",
385 164, "rebase/.git/rebase-merge/rewritten");
387 git_annotated_commit_free(branch_head
);
388 git_annotated_commit_free(upstream_head
);
389 git_reference_free(branch_ref
);
390 git_reference_free(upstream_ref
);
391 git_rebase_free(rebase
);
394 void test_rebase_merge__commit_drops_already_applied(void)
397 git_reference
*branch_ref
, *upstream_ref
;
398 git_annotated_commit
*branch_head
, *upstream_head
;
399 git_rebase_operation
*rebase_operation
;
403 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
404 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/green_pea"));
406 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
407 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
409 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
411 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
412 cl_git_fail(error
= git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
415 cl_assert_equal_i(GIT_EAPPLIED
, error
);
417 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
418 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
421 cl_assert_equal_file(
422 "8d1f13f93c4995760ac07d129246ac1ff64c0be9 2ac4fb7b74c1287f6c792acad759e1ec01e18dae\n",
423 82, "rebase/.git/rebase-merge/rewritten");
425 git_annotated_commit_free(branch_head
);
426 git_annotated_commit_free(upstream_head
);
427 git_reference_free(branch_ref
);
428 git_reference_free(upstream_ref
);
429 git_rebase_free(rebase
);
432 void test_rebase_merge__finish(void)
435 git_reference
*branch_ref
, *upstream_ref
, *head_ref
;
436 git_annotated_commit
*branch_head
, *upstream_head
;
437 git_rebase_operation
*rebase_operation
;
440 const git_reflog_entry
*reflog_entry
;
443 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/gravy"));
444 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/veal"));
446 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
447 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
449 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
451 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
452 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
455 cl_git_fail(error
= git_rebase_next(&rebase_operation
, rebase
));
456 cl_assert_equal_i(GIT_ITEROVER
, error
);
458 cl_git_pass(git_rebase_finish(rebase
, signature
));
460 cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE
, git_repository_state(repo
));
462 cl_git_pass(git_reference_lookup(&head_ref
, repo
, "HEAD"));
463 cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC
, git_reference_type(head_ref
));
464 cl_assert_equal_s("refs/heads/gravy", git_reference_symbolic_target(head_ref
));
466 /* Make sure the reflogs are updated appropriately */
467 cl_git_pass(git_reflog_read(&reflog
, repo
, "HEAD"));
468 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
469 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_old(reflog_entry
));
470 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
471 cl_assert_equal_s("rebase finished: returning to refs/heads/gravy", git_reflog_entry_message(reflog_entry
));
472 git_reflog_free(reflog
);
474 cl_git_pass(git_reflog_read(&reflog
, repo
, "refs/heads/gravy"));
475 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
476 cl_assert_equal_oid(git_annotated_commit_id(branch_head
), git_reflog_entry_id_old(reflog_entry
));
477 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
478 cl_assert_equal_s("rebase finished: refs/heads/gravy onto f87d14a4a236582a0278a916340a793714256864", git_reflog_entry_message(reflog_entry
));
480 git_reflog_free(reflog
);
481 git_annotated_commit_free(branch_head
);
482 git_annotated_commit_free(upstream_head
);
483 git_reference_free(head_ref
);
484 git_reference_free(branch_ref
);
485 git_reference_free(upstream_ref
);
486 git_rebase_free(rebase
);
489 void test_rebase_merge__detached_finish(void)
492 git_reference
*branch_ref
, *upstream_ref
, *head_ref
;
493 git_annotated_commit
*branch_head
, *upstream_head
;
494 git_rebase_operation
*rebase_operation
;
497 const git_reflog_entry
*reflog_entry
;
498 git_checkout_options opts
= GIT_CHECKOUT_OPTIONS_INIT
;
501 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/gravy"));
502 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/veal"));
504 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
505 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
507 cl_git_pass(git_repository_set_head_detached_from_annotated(repo
, branch_head
));
508 opts
.checkout_strategy
= GIT_CHECKOUT_FORCE
;
509 git_checkout_head(repo
, &opts
);
511 cl_git_pass(git_rebase_init(&rebase
, repo
, NULL
, upstream_head
, NULL
, NULL
));
513 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
514 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
517 cl_git_fail(error
= git_rebase_next(&rebase_operation
, rebase
));
518 cl_assert_equal_i(GIT_ITEROVER
, error
);
520 cl_git_pass(git_rebase_finish(rebase
, signature
));
522 cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE
, git_repository_state(repo
));
524 cl_git_pass(git_reference_lookup(&head_ref
, repo
, "HEAD"));
525 cl_assert_equal_i(GIT_REFERENCE_DIRECT
, git_reference_type(head_ref
));
527 /* Make sure the reflogs are updated appropriately */
528 cl_git_pass(git_reflog_read(&reflog
, repo
, "HEAD"));
529 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
530 cl_assert_equal_oid(git_annotated_commit_id(upstream_head
), git_reflog_entry_id_old(reflog_entry
));
531 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
533 git_reflog_free(reflog
);
534 git_annotated_commit_free(branch_head
);
535 git_annotated_commit_free(upstream_head
);
536 git_reference_free(head_ref
);
537 git_reference_free(branch_ref
);
538 git_reference_free(upstream_ref
);
539 git_rebase_free(rebase
);
542 void test_rebase_merge__finish_with_ids(void)
545 git_reference
*head_ref
;
546 git_oid branch_id
, upstream_id
;
547 git_annotated_commit
*branch_head
, *upstream_head
;
548 git_rebase_operation
*rebase_operation
;
551 const git_reflog_entry
*reflog_entry
;
554 cl_git_pass(git_oid_fromstr(&branch_id
, "d616d97082eb7bb2dc6f180a7cca940993b7a56f"));
555 cl_git_pass(git_oid_fromstr(&upstream_id
, "f87d14a4a236582a0278a916340a793714256864"));
557 cl_git_pass(git_annotated_commit_lookup(&branch_head
, repo
, &branch_id
));
558 cl_git_pass(git_annotated_commit_lookup(&upstream_head
, repo
, &upstream_id
));
560 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
562 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
563 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
566 cl_git_fail(error
= git_rebase_next(&rebase_operation
, rebase
));
567 cl_assert_equal_i(GIT_ITEROVER
, error
);
569 cl_git_pass(git_rebase_finish(rebase
, signature
));
571 cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE
, git_repository_state(repo
));
573 cl_git_pass(git_reference_lookup(&head_ref
, repo
, "HEAD"));
574 cl_assert_equal_i(GIT_REFERENCE_DIRECT
, git_reference_type(head_ref
));
575 cl_assert_equal_oid(&commit_id
, git_reference_target(head_ref
));
577 /* reflogs are not updated as if we were operating on proper
578 * branches. check that the last reflog entry is the rebase.
580 cl_git_pass(git_reflog_read(&reflog
, repo
, "HEAD"));
581 cl_assert(reflog_entry
= git_reflog_entry_byindex(reflog
, 0));
582 cl_assert_equal_oid(&commit_id
, git_reflog_entry_id_new(reflog_entry
));
583 cl_assert_equal_s("rebase: Modification 3 to gravy", git_reflog_entry_message(reflog_entry
));
584 git_reflog_free(reflog
);
586 git_annotated_commit_free(branch_head
);
587 git_annotated_commit_free(upstream_head
);
588 git_reference_free(head_ref
);
589 git_rebase_free(rebase
);
592 void test_rebase_merge__no_common_ancestor(void)
595 git_reference
*branch_ref
, *upstream_ref
;
596 git_annotated_commit
*branch_head
, *upstream_head
;
597 git_rebase_operation
*rebase_operation
;
598 git_oid commit_id
, expected_final_id
;
600 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/barley"));
601 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
603 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
604 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
606 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
608 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
609 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
612 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
613 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
616 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
617 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
620 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
621 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
624 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
625 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
628 cl_git_pass(git_rebase_finish(rebase
, signature
));
630 git_oid_fromstr(&expected_final_id
, "71e7ee8d4fe7d8bf0d107355197e0a953dfdb7f3");
631 cl_assert_equal_oid(&expected_final_id
, &commit_id
);
633 git_annotated_commit_free(branch_head
);
634 git_annotated_commit_free(upstream_head
);
635 git_reference_free(branch_ref
);
636 git_reference_free(upstream_ref
);
637 git_rebase_free(rebase
);
640 static void test_copy_note(
641 const git_rebase_options
*opts
,
645 git_reference
*branch_ref
, *upstream_ref
;
646 git_annotated_commit
*branch_head
, *upstream_head
;
647 git_commit
*branch_commit
;
648 git_rebase_operation
*rebase_operation
;
649 git_oid note_id
, commit_id
;
650 git_note
*note
= NULL
;
653 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/gravy"));
654 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/veal"));
656 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
657 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
659 cl_git_pass(git_reference_peel((git_object
**)&branch_commit
,
660 branch_ref
, GIT_OBJECT_COMMIT
));
662 /* Add a note to a commit */
663 cl_git_pass(git_note_create(¬e_id
, repo
, "refs/notes/test",
664 git_commit_author(branch_commit
), git_commit_committer(branch_commit
),
665 git_commit_id(branch_commit
),
666 "This is a commit note.", 0));
668 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, opts
));
670 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
671 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
674 cl_git_pass(git_rebase_finish(rebase
, signature
));
676 cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE
, git_repository_state(repo
));
679 cl_git_pass(git_note_read(¬e
, repo
, "refs/notes/test", &commit_id
));
680 cl_assert_equal_s("This is a commit note.", git_note_message(note
));
683 git_note_read(¬e
, repo
, "refs/notes/test", &commit_id
));
684 cl_assert_equal_i(GIT_ENOTFOUND
, error
);
688 git_commit_free(branch_commit
);
689 git_annotated_commit_free(branch_head
);
690 git_annotated_commit_free(upstream_head
);
691 git_reference_free(branch_ref
);
692 git_reference_free(upstream_ref
);
693 git_rebase_free(rebase
);
696 void test_rebase_merge__copy_notes_off_by_default(void)
698 test_copy_note(NULL
, 0);
701 void test_rebase_merge__copy_notes_specified_in_options(void)
703 git_rebase_options opts
= GIT_REBASE_OPTIONS_INIT
;
704 opts
.rewrite_notes_ref
= "refs/notes/test";
706 test_copy_note(&opts
, 1);
709 void test_rebase_merge__copy_notes_specified_in_config(void)
713 cl_git_pass(git_repository_config(&config
, repo
));
714 cl_git_pass(git_config_set_string(config
,
715 "notes.rewriteRef", "refs/notes/test"));
717 test_copy_note(NULL
, 1);
720 void test_rebase_merge__copy_notes_disabled_in_config(void)
724 cl_git_pass(git_repository_config(&config
, repo
));
725 cl_git_pass(git_config_set_bool(config
, "notes.rewrite.rebase", 0));
726 cl_git_pass(git_config_set_string(config
,
727 "notes.rewriteRef", "refs/notes/test"));
729 test_copy_note(NULL
, 0);
732 void rebase_checkout_progress_cb(
734 size_t completed_steps
,
738 int *called
= payload
;
741 GIT_UNUSED(completed_steps
);
742 GIT_UNUSED(total_steps
);
747 void test_rebase_merge__custom_checkout_options(void)
750 git_reference
*branch_ref
, *upstream_ref
;
751 git_annotated_commit
*branch_head
, *upstream_head
;
752 git_rebase_options rebase_options
= GIT_REBASE_OPTIONS_INIT
;
753 git_checkout_options checkout_options
= GIT_CHECKOUT_OPTIONS_INIT
;
754 git_rebase_operation
*rebase_operation
;
757 checkout_options
.progress_cb
= rebase_checkout_progress_cb
;
758 checkout_options
.progress_payload
= &called
;
760 memcpy(&rebase_options
.checkout_options
, &checkout_options
,
761 sizeof(git_checkout_options
));
763 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/beef"));
764 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
766 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
767 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
770 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, &rebase_options
));
771 cl_assert_equal_i(1, called
);
774 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
775 cl_assert_equal_i(1, called
);
778 cl_git_pass(git_rebase_abort(rebase
));
779 cl_assert_equal_i(1, called
);
781 git_annotated_commit_free(branch_head
);
782 git_annotated_commit_free(upstream_head
);
783 git_reference_free(branch_ref
);
784 git_reference_free(upstream_ref
);
785 git_rebase_free(rebase
);
788 void test_rebase_merge__custom_merge_options(void)
791 git_reference
*branch_ref
, *upstream_ref
;
792 git_annotated_commit
*branch_head
, *upstream_head
;
793 git_rebase_options rebase_options
= GIT_REBASE_OPTIONS_INIT
;
794 git_rebase_operation
*rebase_operation
;
796 rebase_options
.merge_options
.flags
|=
797 GIT_MERGE_FAIL_ON_CONFLICT
|
800 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/asparagus"));
801 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/master"));
803 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
804 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
806 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, &rebase_options
));
808 cl_git_fail_with(GIT_EMERGECONFLICT
, git_rebase_next(&rebase_operation
, rebase
));
810 git_annotated_commit_free(branch_head
);
811 git_annotated_commit_free(upstream_head
);
812 git_reference_free(branch_ref
);
813 git_reference_free(upstream_ref
);
814 git_rebase_free(rebase
);
817 void test_rebase_merge__with_directories(void)
820 git_reference
*branch_ref
, *upstream_ref
;
821 git_annotated_commit
*branch_head
, *upstream_head
;
822 git_rebase_operation
*rebase_operation
;
823 git_oid commit_id
, tree_id
;
826 git_oid_fromstr(&tree_id
, "a4d6d9c3d57308fd8e320cf2525bae8f1adafa57");
828 cl_git_pass(git_reference_lookup(&branch_ref
, repo
, "refs/heads/deep_gravy"));
829 cl_git_pass(git_reference_lookup(&upstream_ref
, repo
, "refs/heads/veal"));
831 cl_git_pass(git_annotated_commit_from_ref(&branch_head
, repo
, branch_ref
));
832 cl_git_pass(git_annotated_commit_from_ref(&upstream_head
, repo
, upstream_ref
));
834 cl_git_pass(git_rebase_init(&rebase
, repo
, branch_head
, upstream_head
, NULL
, NULL
));
836 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
837 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
840 cl_git_pass(git_rebase_next(&rebase_operation
, rebase
));
841 cl_git_pass(git_rebase_commit(&commit_id
, rebase
, NULL
, signature
,
844 cl_git_fail_with(GIT_ITEROVER
, git_rebase_next(&rebase_operation
, rebase
));
846 cl_git_pass(git_commit_lookup(&commit
, repo
, &commit_id
));
847 cl_assert_equal_oid(&tree_id
, git_commit_tree_id(commit
));
849 git_commit_free(commit
);
850 git_annotated_commit_free(branch_head
);
851 git_annotated_commit_free(upstream_head
);
852 git_reference_free(branch_ref
);
853 git_reference_free(upstream_ref
);
854 git_rebase_free(rebase
);