]> git.proxmox.com Git - libgit2.git/blob - src/merge.c
New upstream version 1.1.0+dfsg.1
[libgit2.git] / src / merge.c
1 /*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8 #include "merge.h"
9
10 #include "posix.h"
11 #include "buffer.h"
12 #include "repository.h"
13 #include "revwalk.h"
14 #include "commit_list.h"
15 #include "path.h"
16 #include "refs.h"
17 #include "object.h"
18 #include "iterator.h"
19 #include "refs.h"
20 #include "diff.h"
21 #include "diff_generate.h"
22 #include "diff_tform.h"
23 #include "checkout.h"
24 #include "tree.h"
25 #include "blob.h"
26 #include "oid.h"
27 #include "index.h"
28 #include "filebuf.h"
29 #include "config.h"
30 #include "oidarray.h"
31 #include "annotated_commit.h"
32 #include "commit.h"
33 #include "oidarray.h"
34 #include "merge_driver.h"
35 #include "oidmap.h"
36 #include "array.h"
37
38 #include "git2/types.h"
39 #include "git2/repository.h"
40 #include "git2/object.h"
41 #include "git2/commit.h"
42 #include "git2/merge.h"
43 #include "git2/refs.h"
44 #include "git2/reset.h"
45 #include "git2/checkout.h"
46 #include "git2/signature.h"
47 #include "git2/config.h"
48 #include "git2/tree.h"
49 #include "git2/oidarray.h"
50 #include "git2/annotated_commit.h"
51 #include "git2/sys/index.h"
52 #include "git2/sys/hashsig.h"
53
54 #define GIT_MERGE_INDEX_ENTRY_EXISTS(X) ((X).mode != 0)
55 #define GIT_MERGE_INDEX_ENTRY_ISFILE(X) S_ISREG((X).mode)
56
57
58 typedef enum {
59 TREE_IDX_ANCESTOR = 0,
60 TREE_IDX_OURS = 1,
61 TREE_IDX_THEIRS = 2
62 } merge_tree_index_t;
63
64 /* Tracks D/F conflicts */
65 struct merge_diff_df_data {
66 const char *df_path;
67 const char *prev_path;
68 git_merge_diff *prev_conflict;
69 };
70
71 /*
72 * This acts as a negative cache entry marker. In case we've tried to calculate
73 * similarity metrics for a given blob already but `git_hashsig` determined
74 * that it's too small in order to have a meaningful hash signature, we will
75 * insert the address of this marker instead of `NULL`. Like this, we can
76 * easily check whether we have checked a gien entry already and skip doing the
77 * calculation again and again.
78 */
79 static int cache_invalid_marker;
80
81 /* Merge base computation */
82
83 static int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, git_repository *repo, size_t length, const git_oid input_array[])
84 {
85 git_revwalk *walk = NULL;
86 git_vector list;
87 git_commit_list *result = NULL;
88 git_commit_list_node *commit;
89 int error = -1;
90 unsigned int i;
91
92 if (length < 2) {
93 git_error_set(GIT_ERROR_INVALID, "at least two commits are required to find an ancestor");
94 return -1;
95 }
96
97 if (git_vector_init(&list, length - 1, NULL) < 0)
98 return -1;
99
100 if (git_revwalk_new(&walk, repo) < 0)
101 goto on_error;
102
103 for (i = 1; i < length; i++) {
104 commit = git_revwalk__commit_lookup(walk, &input_array[i]);
105 if (commit == NULL)
106 goto on_error;
107
108 git_vector_insert(&list, commit);
109 }
110
111 commit = git_revwalk__commit_lookup(walk, &input_array[0]);
112 if (commit == NULL)
113 goto on_error;
114
115 if (git_merge__bases_many(&result, walk, commit, &list) < 0)
116 goto on_error;
117
118 if (!result) {
119 git_error_set(GIT_ERROR_MERGE, "no merge base found");
120 error = GIT_ENOTFOUND;
121 goto on_error;
122 }
123
124 *out = result;
125 *walk_out = walk;
126
127 git_vector_free(&list);
128 return 0;
129
130 on_error:
131 git_vector_free(&list);
132 git_revwalk_free(walk);
133 return error;
134 }
135
136 int git_merge_base_many(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[])
137 {
138 git_revwalk *walk;
139 git_commit_list *result = NULL;
140 int error = 0;
141
142 assert(out && repo && input_array);
143
144 if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0)
145 return error;
146
147 git_oid_cpy(out, &result->item->oid);
148
149 git_commit_list_free(&result);
150 git_revwalk_free(walk);
151
152 return 0;
153 }
154
155 int git_merge_bases_many(git_oidarray *out, git_repository *repo, size_t length, const git_oid input_array[])
156 {
157 git_revwalk *walk;
158 git_commit_list *list, *result = NULL;
159 int error = 0;
160 git_array_oid_t array;
161
162 assert(out && repo && input_array);
163
164 if ((error = merge_bases_many(&result, &walk, repo, length, input_array)) < 0)
165 return error;
166
167 git_array_init(array);
168
169 list = result;
170 while (list) {
171 git_oid *id = git_array_alloc(array);
172 if (id == NULL) {
173 error = -1;
174 goto cleanup;
175 }
176
177 git_oid_cpy(id, &list->item->oid);
178 list = list->next;
179 }
180
181 git_oidarray__from_array(out, &array);
182
183 cleanup:
184 git_commit_list_free(&result);
185 git_revwalk_free(walk);
186
187 return error;
188 }
189
190 int git_merge_base_octopus(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[])
191 {
192 git_oid result;
193 unsigned int i;
194 int error = -1;
195
196 assert(out && repo && input_array);
197
198 if (length < 2) {
199 git_error_set(GIT_ERROR_INVALID, "at least two commits are required to find an ancestor");
200 return -1;
201 }
202
203 result = input_array[0];
204 for (i = 1; i < length; i++) {
205 error = git_merge_base(&result, repo, &result, &input_array[i]);
206 if (error < 0)
207 return error;
208 }
209
210 *out = result;
211
212 return 0;
213 }
214
215 static int merge_bases(git_commit_list **out, git_revwalk **walk_out, git_repository *repo, const git_oid *one, const git_oid *two)
216 {
217 git_revwalk *walk;
218 git_vector list;
219 git_commit_list *result = NULL;
220 git_commit_list_node *commit;
221 void *contents[1];
222
223 if (git_revwalk_new(&walk, repo) < 0)
224 return -1;
225
226 commit = git_revwalk__commit_lookup(walk, two);
227 if (commit == NULL)
228 goto on_error;
229
230 /* This is just one value, so we can do it on the stack */
231 memset(&list, 0x0, sizeof(git_vector));
232 contents[0] = commit;
233 list.length = 1;
234 list.contents = contents;
235
236 commit = git_revwalk__commit_lookup(walk, one);
237 if (commit == NULL)
238 goto on_error;
239
240 if (git_merge__bases_many(&result, walk, commit, &list) < 0)
241 goto on_error;
242
243 if (!result) {
244 git_revwalk_free(walk);
245 git_error_set(GIT_ERROR_MERGE, "no merge base found");
246 return GIT_ENOTFOUND;
247 }
248
249 *out = result;
250 *walk_out = walk;
251
252 return 0;
253
254 on_error:
255 git_revwalk_free(walk);
256 return -1;
257
258 }
259
260 int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two)
261 {
262 int error;
263 git_revwalk *walk;
264 git_commit_list *result;
265
266 if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
267 return error;
268
269 git_oid_cpy(out, &result->item->oid);
270 git_commit_list_free(&result);
271 git_revwalk_free(walk);
272
273 return 0;
274 }
275
276 int git_merge_bases(git_oidarray *out, git_repository *repo, const git_oid *one, const git_oid *two)
277 {
278 int error;
279 git_revwalk *walk;
280 git_commit_list *result, *list;
281 git_array_oid_t array;
282
283 git_array_init(array);
284
285 if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
286 return error;
287
288 list = result;
289 while (list) {
290 git_oid *id = git_array_alloc(array);
291 if (id == NULL)
292 goto on_error;
293
294 git_oid_cpy(id, &list->item->oid);
295 list = list->next;
296 }
297
298 git_oidarray__from_array(out, &array);
299 git_commit_list_free(&result);
300 git_revwalk_free(walk);
301
302 return 0;
303
304 on_error:
305 git_commit_list_free(&result);
306 git_revwalk_free(walk);
307 return -1;
308 }
309
310 static int interesting(git_pqueue *list)
311 {
312 size_t i;
313
314 for (i = 0; i < git_pqueue_size(list); i++) {
315 git_commit_list_node *commit = git_pqueue_get(list, i);
316 if ((commit->flags & STALE) == 0)
317 return 1;
318 }
319
320 return 0;
321 }
322
323 static int clear_commit_marks_1(git_commit_list **plist,
324 git_commit_list_node *commit, unsigned int mark)
325 {
326 while (commit) {
327 unsigned int i;
328
329 if (!(mark & commit->flags))
330 return 0;
331
332 commit->flags &= ~mark;
333
334 for (i = 1; i < commit->out_degree; i++) {
335 git_commit_list_node *p = commit->parents[i];
336 if (git_commit_list_insert(p, plist) == NULL)
337 return -1;
338 }
339
340 commit = commit->out_degree ? commit->parents[0] : NULL;
341 }
342
343 return 0;
344 }
345
346 static int clear_commit_marks_many(git_vector *commits, unsigned int mark)
347 {
348 git_commit_list *list = NULL;
349 git_commit_list_node *c;
350 unsigned int i;
351
352 git_vector_foreach(commits, i, c) {
353 if (git_commit_list_insert(c, &list) == NULL)
354 return -1;
355 }
356
357 while (list)
358 if (clear_commit_marks_1(&list, git_commit_list_pop(&list), mark) < 0)
359 return -1;
360 return 0;
361 }
362
363 static int clear_commit_marks(git_commit_list_node *commit, unsigned int mark)
364 {
365 git_commit_list *list = NULL;
366 if (git_commit_list_insert(commit, &list) == NULL)
367 return -1;
368 while (list)
369 if (clear_commit_marks_1(&list, git_commit_list_pop(&list), mark) < 0)
370 return -1;
371 return 0;
372 }
373
374 static int paint_down_to_common(
375 git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos)
376 {
377 git_pqueue list;
378 git_commit_list *result = NULL;
379 git_commit_list_node *two;
380
381 int error;
382 unsigned int i;
383
384 if (git_pqueue_init(&list, 0, twos->length * 2, git_commit_list_time_cmp) < 0)
385 return -1;
386
387 one->flags |= PARENT1;
388 if (git_pqueue_insert(&list, one) < 0)
389 return -1;
390
391 git_vector_foreach(twos, i, two) {
392 if (git_commit_list_parse(walk, two) < 0)
393 return -1;
394
395 two->flags |= PARENT2;
396
397 if (git_pqueue_insert(&list, two) < 0)
398 return -1;
399 }
400
401 /* as long as there are non-STALE commits */
402 while (interesting(&list)) {
403 git_commit_list_node *commit = git_pqueue_pop(&list);
404 int flags;
405
406 if (commit == NULL)
407 break;
408
409 flags = commit->flags & (PARENT1 | PARENT2 | STALE);
410 if (flags == (PARENT1 | PARENT2)) {
411 if (!(commit->flags & RESULT)) {
412 commit->flags |= RESULT;
413 if (git_commit_list_insert(commit, &result) == NULL)
414 return -1;
415 }
416 /* we mark the parents of a merge stale */
417 flags |= STALE;
418 }
419
420 for (i = 0; i < commit->out_degree; i++) {
421 git_commit_list_node *p = commit->parents[i];
422 if ((p->flags & flags) == flags)
423 continue;
424
425 if ((error = git_commit_list_parse(walk, p)) < 0)
426 return error;
427
428 p->flags |= flags;
429 if (git_pqueue_insert(&list, p) < 0)
430 return -1;
431 }
432 }
433
434 git_pqueue_free(&list);
435 *out = result;
436 return 0;
437 }
438
439 static int remove_redundant(git_revwalk *walk, git_vector *commits)
440 {
441 git_vector work = GIT_VECTOR_INIT;
442 unsigned char *redundant;
443 unsigned int *filled_index;
444 unsigned int i, j;
445 int error = 0;
446
447 redundant = git__calloc(commits->length, 1);
448 GIT_ERROR_CHECK_ALLOC(redundant);
449 filled_index = git__calloc((commits->length - 1), sizeof(unsigned int));
450 GIT_ERROR_CHECK_ALLOC(filled_index);
451
452 for (i = 0; i < commits->length; ++i) {
453 if ((error = git_commit_list_parse(walk, commits->contents[i])) < 0)
454 goto done;
455 }
456
457 for (i = 0; i < commits->length; ++i) {
458 git_commit_list *common = NULL;
459 git_commit_list_node *commit = commits->contents[i];
460
461 if (redundant[i])
462 continue;
463
464 git_vector_clear(&work);
465
466 for (j = 0; j < commits->length; j++) {
467 if (i == j || redundant[j])
468 continue;
469
470 filled_index[work.length] = j;
471 if ((error = git_vector_insert(&work, commits->contents[j])) < 0)
472 goto done;
473 }
474
475 error = paint_down_to_common(&common, walk, commit, &work);
476 if (error < 0)
477 goto done;
478
479 if (commit->flags & PARENT2)
480 redundant[i] = 1;
481
482 for (j = 0; j < work.length; j++) {
483 git_commit_list_node *w = work.contents[j];
484 if (w->flags & PARENT1)
485 redundant[filled_index[j]] = 1;
486 }
487
488 git_commit_list_free(&common);
489
490 if ((error = clear_commit_marks(commit, ALL_FLAGS)) < 0 ||
491 (error = clear_commit_marks_many(&work, ALL_FLAGS)) < 0)
492 goto done;
493 }
494
495 for (i = 0; i < commits->length; ++i) {
496 if (redundant[i])
497 commits->contents[i] = NULL;
498 }
499
500 done:
501 git__free(redundant);
502 git__free(filled_index);
503 git_vector_free(&work);
504 return error;
505 }
506
507 int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos)
508 {
509 int error;
510 unsigned int i;
511 git_commit_list_node *two;
512 git_commit_list *result = NULL, *tmp = NULL;
513
514 /* If there's only the one commit, there can be no merge bases */
515 if (twos->length == 0) {
516 *out = NULL;
517 return 0;
518 }
519
520 /* if the commit is repeated, we have a our merge base already */
521 git_vector_foreach(twos, i, two) {
522 if (one == two)
523 return git_commit_list_insert(one, out) ? 0 : -1;
524 }
525
526 if (git_commit_list_parse(walk, one) < 0)
527 return -1;
528
529 error = paint_down_to_common(&result, walk, one, twos);
530 if (error < 0)
531 return error;
532
533 /* filter out any stale commits in the results */
534 tmp = result;
535 result = NULL;
536
537 while (tmp) {
538 git_commit_list_node *c = git_commit_list_pop(&tmp);
539 if (!(c->flags & STALE))
540 if (git_commit_list_insert_by_date(c, &result) == NULL)
541 return -1;
542 }
543
544 /*
545 * more than one merge base -- see if there are redundant merge
546 * bases and remove them
547 */
548 if (result && result->next) {
549 git_vector redundant = GIT_VECTOR_INIT;
550
551 while (result)
552 git_vector_insert(&redundant, git_commit_list_pop(&result));
553
554 if ((error = clear_commit_marks(one, ALL_FLAGS)) < 0 ||
555 (error = clear_commit_marks_many(twos, ALL_FLAGS)) < 0 ||
556 (error = remove_redundant(walk, &redundant)) < 0) {
557 git_vector_free(&redundant);
558 return error;
559 }
560
561 git_vector_foreach(&redundant, i, two) {
562 if (two != NULL)
563 git_commit_list_insert_by_date(two, &result);
564 }
565
566 git_vector_free(&redundant);
567 }
568
569 *out = result;
570 return 0;
571 }
572
573 int git_repository_mergehead_foreach(
574 git_repository *repo,
575 git_repository_mergehead_foreach_cb cb,
576 void *payload)
577 {
578 git_buf merge_head_path = GIT_BUF_INIT, merge_head_file = GIT_BUF_INIT;
579 char *buffer, *line;
580 size_t line_num = 1;
581 git_oid oid;
582 int error = 0;
583
584 assert(repo && cb);
585
586 if ((error = git_buf_joinpath(&merge_head_path, repo->gitdir,
587 GIT_MERGE_HEAD_FILE)) < 0)
588 return error;
589
590 if ((error = git_futils_readbuffer(&merge_head_file,
591 git_buf_cstr(&merge_head_path))) < 0)
592 goto cleanup;
593
594 buffer = merge_head_file.ptr;
595
596 while ((line = git__strsep(&buffer, "\n")) != NULL) {
597 if (strlen(line) != GIT_OID_HEXSZ) {
598 git_error_set(GIT_ERROR_INVALID, "unable to parse OID - invalid length");
599 error = -1;
600 goto cleanup;
601 }
602
603 if ((error = git_oid_fromstr(&oid, line)) < 0)
604 goto cleanup;
605
606 if ((error = cb(&oid, payload)) != 0) {
607 git_error_set_after_callback(error);
608 goto cleanup;
609 }
610
611 ++line_num;
612 }
613
614 if (*buffer) {
615 git_error_set(GIT_ERROR_MERGE, "no EOL at line %"PRIuZ, line_num);
616 error = -1;
617 goto cleanup;
618 }
619
620 cleanup:
621 git_buf_dispose(&merge_head_path);
622 git_buf_dispose(&merge_head_file);
623
624 return error;
625 }
626
627 GIT_INLINE(int) index_entry_cmp(const git_index_entry *a, const git_index_entry *b)
628 {
629 int value = 0;
630
631 if (a->path == NULL)
632 return (b->path == NULL) ? 0 : 1;
633
634 if ((value = a->mode - b->mode) == 0 &&
635 (value = git_oid__cmp(&a->id, &b->id)) == 0)
636 value = strcmp(a->path, b->path);
637
638 return value;
639 }
640
641 /* Conflict resolution */
642
643 static int merge_conflict_resolve_trivial(
644 int *resolved,
645 git_merge_diff_list *diff_list,
646 const git_merge_diff *conflict)
647 {
648 int ours_empty, theirs_empty;
649 int ours_changed, theirs_changed, ours_theirs_differ;
650 git_index_entry const *result = NULL;
651 int error = 0;
652
653 assert(resolved && diff_list && conflict);
654
655 *resolved = 0;
656
657 if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE ||
658 conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
659 return 0;
660
661 if (conflict->our_status == GIT_DELTA_RENAMED ||
662 conflict->their_status == GIT_DELTA_RENAMED)
663 return 0;
664
665 ours_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry);
666 theirs_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry);
667
668 ours_changed = (conflict->our_status != GIT_DELTA_UNMODIFIED);
669 theirs_changed = (conflict->their_status != GIT_DELTA_UNMODIFIED);
670 ours_theirs_differ = ours_changed && theirs_changed &&
671 index_entry_cmp(&conflict->our_entry, &conflict->their_entry);
672
673 /*
674 * Note: with only one ancestor, some cases are not distinct:
675 *
676 * 16: ancest:anc1/anc2, head:anc1, remote:anc2 = result:no merge
677 * 3: ancest:(empty)^, head:head, remote:(empty) = result:no merge
678 * 2: ancest:(empty)^, head:(empty), remote:remote = result:no merge
679 *
680 * Note that the two cases that take D/F conflicts into account
681 * specifically do not need to be explicitly tested, as D/F conflicts
682 * would fail the *empty* test:
683 *
684 * 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head
685 * 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote
686 *
687 * Note that many of these cases need not be explicitly tested, as
688 * they simply degrade to "all different" cases (eg, 11):
689 *
690 * 4: ancest:(empty)^, head:head, remote:remote = result:no merge
691 * 7: ancest:ancest+, head:(empty), remote:remote = result:no merge
692 * 9: ancest:ancest+, head:head, remote:(empty) = result:no merge
693 * 11: ancest:ancest+, head:head, remote:remote = result:no merge
694 */
695
696 /* 5ALT: ancest:*, head:head, remote:head = result:head */
697 if (ours_changed && !ours_empty && !ours_theirs_differ)
698 result = &conflict->our_entry;
699 /* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */
700 else if (ours_changed && ours_empty && theirs_empty)
701 *resolved = 0;
702 /* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */
703 else if (ours_empty && !theirs_changed)
704 *resolved = 0;
705 /* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */
706 else if (!ours_changed && theirs_empty)
707 *resolved = 0;
708 /* 13: ancest:ancest+, head:head, remote:ancest = result:head */
709 else if (ours_changed && !theirs_changed)
710 result = &conflict->our_entry;
711 /* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */
712 else if (!ours_changed && theirs_changed)
713 result = &conflict->their_entry;
714 else
715 *resolved = 0;
716
717 if (result != NULL &&
718 GIT_MERGE_INDEX_ENTRY_EXISTS(*result) &&
719 (error = git_vector_insert(&diff_list->staged, (void *)result)) >= 0)
720 *resolved = 1;
721
722 /* Note: trivial resolution does not update the REUC. */
723
724 return error;
725 }
726
727 static int merge_conflict_resolve_one_removed(
728 int *resolved,
729 git_merge_diff_list *diff_list,
730 const git_merge_diff *conflict)
731 {
732 int ours_empty, theirs_empty;
733 int ours_changed, theirs_changed;
734 int error = 0;
735
736 assert(resolved && diff_list && conflict);
737
738 *resolved = 0;
739
740 if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE ||
741 conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
742 return 0;
743
744 ours_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry);
745 theirs_empty = !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry);
746
747 ours_changed = (conflict->our_status != GIT_DELTA_UNMODIFIED);
748 theirs_changed = (conflict->their_status != GIT_DELTA_UNMODIFIED);
749
750 /* Removed in both */
751 if (ours_changed && ours_empty && theirs_empty)
752 *resolved = 1;
753 /* Removed in ours */
754 else if (ours_empty && !theirs_changed)
755 *resolved = 1;
756 /* Removed in theirs */
757 else if (!ours_changed && theirs_empty)
758 *resolved = 1;
759
760 if (*resolved)
761 git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
762
763 return error;
764 }
765
766 static int merge_conflict_resolve_one_renamed(
767 int *resolved,
768 git_merge_diff_list *diff_list,
769 const git_merge_diff *conflict)
770 {
771 int ours_renamed, theirs_renamed;
772 int ours_changed, theirs_changed;
773 git_index_entry *merged;
774 int error = 0;
775
776 assert(resolved && diff_list && conflict);
777
778 *resolved = 0;
779
780 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
781 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
782 return 0;
783
784 ours_renamed = (conflict->our_status == GIT_DELTA_RENAMED);
785 theirs_renamed = (conflict->their_status == GIT_DELTA_RENAMED);
786
787 if (!ours_renamed && !theirs_renamed)
788 return 0;
789
790 /* Reject one file in a 2->1 conflict */
791 if (conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 ||
792 conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2 ||
793 conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
794 return 0;
795
796 ours_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->our_entry.id) != 0);
797 theirs_changed = (git_oid__cmp(&conflict->ancestor_entry.id, &conflict->their_entry.id) != 0);
798
799 /* if both are modified (and not to a common target) require a merge */
800 if (ours_changed && theirs_changed &&
801 git_oid__cmp(&conflict->our_entry.id, &conflict->their_entry.id) != 0)
802 return 0;
803
804 if ((merged = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry))) == NULL)
805 return -1;
806
807 if (ours_changed)
808 memcpy(merged, &conflict->our_entry, sizeof(git_index_entry));
809 else
810 memcpy(merged, &conflict->their_entry, sizeof(git_index_entry));
811
812 if (ours_renamed)
813 merged->path = conflict->our_entry.path;
814 else
815 merged->path = conflict->their_entry.path;
816
817 *resolved = 1;
818
819 git_vector_insert(&diff_list->staged, merged);
820 git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
821
822 return error;
823 }
824
825 static bool merge_conflict_can_resolve_contents(
826 const git_merge_diff *conflict)
827 {
828 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
829 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
830 return false;
831
832 /* Reject D/F conflicts */
833 if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE)
834 return false;
835
836 /* Reject submodules. */
837 if (S_ISGITLINK(conflict->ancestor_entry.mode) ||
838 S_ISGITLINK(conflict->our_entry.mode) ||
839 S_ISGITLINK(conflict->their_entry.mode))
840 return false;
841
842 /* Reject link/file conflicts. */
843 if ((S_ISLNK(conflict->ancestor_entry.mode) ^
844 S_ISLNK(conflict->our_entry.mode)) ||
845 (S_ISLNK(conflict->ancestor_entry.mode) ^
846 S_ISLNK(conflict->their_entry.mode)))
847 return false;
848
849 /* Reject name conflicts */
850 if (conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 ||
851 conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
852 return false;
853
854 if ((conflict->our_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
855 (conflict->their_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
856 strcmp(conflict->ancestor_entry.path, conflict->their_entry.path) != 0)
857 return false;
858
859 return true;
860 }
861
862 static int merge_conflict_invoke_driver(
863 git_index_entry **out,
864 const char *name,
865 git_merge_driver *driver,
866 git_merge_diff_list *diff_list,
867 git_merge_driver_source *src)
868 {
869 git_index_entry *result;
870 git_buf buf = GIT_BUF_INIT;
871 const char *path;
872 uint32_t mode;
873 git_odb *odb = NULL;
874 git_oid oid;
875 int error;
876
877 *out = NULL;
878
879 if ((error = driver->apply(driver, &path, &mode, &buf, name, src)) < 0 ||
880 (error = git_repository_odb(&odb, src->repo)) < 0 ||
881 (error = git_odb_write(&oid, odb, buf.ptr, buf.size, GIT_OBJECT_BLOB)) < 0)
882 goto done;
883
884 result = git_pool_mallocz(&diff_list->pool, sizeof(git_index_entry));
885 GIT_ERROR_CHECK_ALLOC(result);
886
887 git_oid_cpy(&result->id, &oid);
888 result->mode = mode;
889 result->file_size = (uint32_t)buf.size;
890
891 result->path = git_pool_strdup(&diff_list->pool, path);
892 GIT_ERROR_CHECK_ALLOC(result->path);
893
894 *out = result;
895
896 done:
897 git_buf_dispose(&buf);
898 git_odb_free(odb);
899
900 return error;
901 }
902
903 static int merge_conflict_resolve_contents(
904 int *resolved,
905 git_merge_diff_list *diff_list,
906 const git_merge_diff *conflict,
907 const git_merge_options *merge_opts,
908 const git_merge_file_options *file_opts)
909 {
910 git_merge_driver_source source = {0};
911 git_merge_file_result result = {0};
912 git_merge_driver *driver;
913 git_merge_driver__builtin builtin = {{0}};
914 git_index_entry *merge_result;
915 git_odb *odb = NULL;
916 const char *name;
917 bool fallback = false;
918 int error;
919
920 assert(resolved && diff_list && conflict);
921
922 *resolved = 0;
923
924 if (!merge_conflict_can_resolve_contents(conflict))
925 return 0;
926
927 source.repo = diff_list->repo;
928 source.default_driver = merge_opts->default_driver;
929 source.file_opts = file_opts;
930 source.ancestor = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
931 &conflict->ancestor_entry : NULL;
932 source.ours = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
933 &conflict->our_entry : NULL;
934 source.theirs = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
935 &conflict->their_entry : NULL;
936
937 if (file_opts->favor != GIT_MERGE_FILE_FAVOR_NORMAL) {
938 /* if the user requested a particular type of resolution (via the
939 * favor flag) then let that override the gitattributes and use
940 * the builtin driver.
941 */
942 name = "text";
943 builtin.base.apply = git_merge_driver__builtin_apply;
944 builtin.favor = file_opts->favor;
945
946 driver = &builtin.base;
947 } else {
948 /* find the merge driver for this file */
949 if ((error = git_merge_driver_for_source(&name, &driver, &source)) < 0)
950 goto done;
951
952 if (driver == NULL)
953 fallback = true;
954 }
955
956 if (driver) {
957 error = merge_conflict_invoke_driver(&merge_result, name, driver,
958 diff_list, &source);
959
960 if (error == GIT_PASSTHROUGH)
961 fallback = true;
962 }
963
964 if (fallback) {
965 error = merge_conflict_invoke_driver(&merge_result, "text",
966 &git_merge_driver__text.base, diff_list, &source);
967 }
968
969 if (error < 0) {
970 if (error == GIT_EMERGECONFLICT)
971 error = 0;
972
973 goto done;
974 }
975
976 git_vector_insert(&diff_list->staged, merge_result);
977 git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
978
979 *resolved = 1;
980
981 done:
982 git_merge_file_result_free(&result);
983 git_odb_free(odb);
984
985 return error;
986 }
987
988 static int merge_conflict_resolve(
989 int *out,
990 git_merge_diff_list *diff_list,
991 const git_merge_diff *conflict,
992 const git_merge_options *merge_opts,
993 const git_merge_file_options *file_opts)
994 {
995 int resolved = 0;
996 int error = 0;
997
998 *out = 0;
999
1000 if ((error = merge_conflict_resolve_trivial(
1001 &resolved, diff_list, conflict)) < 0)
1002 goto done;
1003
1004 if (!resolved && (error = merge_conflict_resolve_one_removed(
1005 &resolved, diff_list, conflict)) < 0)
1006 goto done;
1007
1008 if (!resolved && (error = merge_conflict_resolve_one_renamed(
1009 &resolved, diff_list, conflict)) < 0)
1010 goto done;
1011
1012 if (!resolved && (error = merge_conflict_resolve_contents(
1013 &resolved, diff_list, conflict, merge_opts, file_opts)) < 0)
1014 goto done;
1015
1016 *out = resolved;
1017
1018 done:
1019 return error;
1020 }
1021
1022 /* Rename detection and coalescing */
1023
1024 struct merge_diff_similarity {
1025 unsigned char similarity;
1026 size_t other_idx;
1027 };
1028
1029 static int index_entry_similarity_calc(
1030 void **out,
1031 git_repository *repo,
1032 git_index_entry *entry,
1033 const git_merge_options *opts)
1034 {
1035 git_blob *blob;
1036 git_diff_file diff_file = {{{0}}};
1037 git_object_size_t blobsize;
1038 int error;
1039
1040 if (*out || *out == &cache_invalid_marker)
1041 return 0;
1042
1043 *out = NULL;
1044
1045 if ((error = git_blob_lookup(&blob, repo, &entry->id)) < 0)
1046 return error;
1047
1048 git_oid_cpy(&diff_file.id, &entry->id);
1049 diff_file.path = entry->path;
1050 diff_file.size = entry->file_size;
1051 diff_file.mode = entry->mode;
1052 diff_file.flags = 0;
1053
1054 blobsize = git_blob_rawsize(blob);
1055
1056 /* file too big for rename processing */
1057 if (!git__is_sizet(blobsize))
1058 return 0;
1059
1060 error = opts->metric->buffer_signature(out, &diff_file,
1061 git_blob_rawcontent(blob), (size_t)blobsize,
1062 opts->metric->payload);
1063 if (error == GIT_EBUFS)
1064 *out = &cache_invalid_marker;
1065
1066 git_blob_free(blob);
1067
1068 return error;
1069 }
1070
1071 static int index_entry_similarity_inexact(
1072 git_repository *repo,
1073 git_index_entry *a,
1074 size_t a_idx,
1075 git_index_entry *b,
1076 size_t b_idx,
1077 void **cache,
1078 const git_merge_options *opts)
1079 {
1080 int score = 0;
1081 int error = 0;
1082
1083 if (!GIT_MODE_ISBLOB(a->mode) || !GIT_MODE_ISBLOB(b->mode))
1084 return 0;
1085
1086 /* update signature cache if needed */
1087 if ((error = index_entry_similarity_calc(&cache[a_idx], repo, a, opts)) < 0 ||
1088 (error = index_entry_similarity_calc(&cache[b_idx], repo, b, opts)) < 0)
1089 return error;
1090
1091 /* some metrics may not wish to process this file (too big / too small) */
1092 if (cache[a_idx] == &cache_invalid_marker || cache[b_idx] == &cache_invalid_marker)
1093 return 0;
1094
1095 /* compare signatures */
1096 if (opts->metric->similarity(&score, cache[a_idx], cache[b_idx], opts->metric->payload) < 0)
1097 return -1;
1098
1099 /* clip score */
1100 if (score < 0)
1101 score = 0;
1102 else if (score > 100)
1103 score = 100;
1104
1105 return score;
1106 }
1107
1108 /* Tracks deletes by oid for merge_diff_mark_similarity_exact(). This is a
1109 * non-shrinking queue where next_pos is the next position to dequeue.
1110 */
1111 typedef struct {
1112 git_array_t(size_t) arr;
1113 size_t next_pos;
1114 size_t first_entry;
1115 } deletes_by_oid_queue;
1116
1117 static void deletes_by_oid_free(git_oidmap *map) {
1118 deletes_by_oid_queue *queue;
1119
1120 if (!map)
1121 return;
1122
1123 git_oidmap_foreach_value(map, queue, {
1124 git_array_clear(queue->arr);
1125 });
1126 git_oidmap_free(map);
1127 }
1128
1129 static int deletes_by_oid_enqueue(git_oidmap *map, git_pool* pool, const git_oid *id, size_t idx)
1130 {
1131 deletes_by_oid_queue *queue;
1132 size_t *array_entry;
1133
1134 if ((queue = git_oidmap_get(map, id)) == NULL) {
1135 queue = git_pool_malloc(pool, sizeof(deletes_by_oid_queue));
1136 GIT_ERROR_CHECK_ALLOC(queue);
1137
1138 git_array_init(queue->arr);
1139 queue->next_pos = 0;
1140 queue->first_entry = idx;
1141
1142 if (git_oidmap_set(map, id, queue) < 0)
1143 return -1;
1144 } else {
1145 array_entry = git_array_alloc(queue->arr);
1146 GIT_ERROR_CHECK_ALLOC(array_entry);
1147 *array_entry = idx;
1148 }
1149
1150 return 0;
1151 }
1152
1153 static int deletes_by_oid_dequeue(size_t *idx, git_oidmap *map, const git_oid *id)
1154 {
1155 deletes_by_oid_queue *queue;
1156 size_t *array_entry;
1157
1158 if ((queue = git_oidmap_get(map, id)) == NULL)
1159 return GIT_ENOTFOUND;
1160
1161 if (queue->next_pos == 0) {
1162 *idx = queue->first_entry;
1163 } else {
1164 array_entry = git_array_get(queue->arr, queue->next_pos - 1);
1165 if (array_entry == NULL)
1166 return GIT_ENOTFOUND;
1167
1168 *idx = *array_entry;
1169 }
1170
1171 queue->next_pos++;
1172 return 0;
1173 }
1174
1175 static int merge_diff_mark_similarity_exact(
1176 git_merge_diff_list *diff_list,
1177 struct merge_diff_similarity *similarity_ours,
1178 struct merge_diff_similarity *similarity_theirs)
1179 {
1180 size_t i, j;
1181 git_merge_diff *conflict_src, *conflict_tgt;
1182 git_oidmap *ours_deletes_by_oid = NULL, *theirs_deletes_by_oid = NULL;
1183 int error = 0;
1184
1185 if (git_oidmap_new(&ours_deletes_by_oid) < 0 ||
1186 git_oidmap_new(&theirs_deletes_by_oid) < 0) {
1187 error = -1;
1188 goto done;
1189 }
1190
1191 /* Build a map of object ids to conflicts */
1192 git_vector_foreach(&diff_list->conflicts, i, conflict_src) {
1193 /* Items can be the source of a rename iff they have an item in the
1194 * ancestor slot and lack an item in the ours or theirs slot. */
1195 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->ancestor_entry))
1196 continue;
1197
1198 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry)) {
1199 error = deletes_by_oid_enqueue(ours_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
1200 if (error < 0)
1201 goto done;
1202 }
1203
1204 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)) {
1205 error = deletes_by_oid_enqueue(theirs_deletes_by_oid, &diff_list->pool, &conflict_src->ancestor_entry.id, i);
1206 if (error < 0)
1207 goto done;
1208 }
1209 }
1210
1211 git_vector_foreach(&diff_list->conflicts, j, conflict_tgt) {
1212 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->ancestor_entry))
1213 continue;
1214
1215 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->our_entry)) {
1216 if (deletes_by_oid_dequeue(&i, ours_deletes_by_oid, &conflict_tgt->our_entry.id) == 0) {
1217 similarity_ours[i].similarity = 100;
1218 similarity_ours[i].other_idx = j;
1219
1220 similarity_ours[j].similarity = 100;
1221 similarity_ours[j].other_idx = i;
1222 }
1223 }
1224
1225 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->their_entry)) {
1226 if (deletes_by_oid_dequeue(&i, theirs_deletes_by_oid, &conflict_tgt->their_entry.id) == 0) {
1227 similarity_theirs[i].similarity = 100;
1228 similarity_theirs[i].other_idx = j;
1229
1230 similarity_theirs[j].similarity = 100;
1231 similarity_theirs[j].other_idx = i;
1232 }
1233 }
1234 }
1235
1236 done:
1237 deletes_by_oid_free(ours_deletes_by_oid);
1238 deletes_by_oid_free(theirs_deletes_by_oid);
1239
1240 return error;
1241 }
1242
1243 static int merge_diff_mark_similarity_inexact(
1244 git_repository *repo,
1245 git_merge_diff_list *diff_list,
1246 struct merge_diff_similarity *similarity_ours,
1247 struct merge_diff_similarity *similarity_theirs,
1248 void **cache,
1249 const git_merge_options *opts)
1250 {
1251 size_t i, j;
1252 git_merge_diff *conflict_src, *conflict_tgt;
1253 int similarity;
1254
1255 git_vector_foreach(&diff_list->conflicts, i, conflict_src) {
1256 /* Items can be the source of a rename iff they have an item in the
1257 * ancestor slot and lack an item in the ours or theirs slot. */
1258 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->ancestor_entry) ||
1259 (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry) &&
1260 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)))
1261 continue;
1262
1263 git_vector_foreach(&diff_list->conflicts, j, conflict_tgt) {
1264 size_t our_idx = diff_list->conflicts.length + j;
1265 size_t their_idx = (diff_list->conflicts.length * 2) + j;
1266
1267 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->ancestor_entry))
1268 continue;
1269
1270 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->our_entry) &&
1271 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->our_entry)) {
1272 similarity = index_entry_similarity_inexact(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->our_entry, our_idx, cache, opts);
1273
1274 if (similarity == GIT_EBUFS)
1275 continue;
1276 else if (similarity < 0)
1277 return similarity;
1278
1279 if (similarity > similarity_ours[i].similarity &&
1280 similarity > similarity_ours[j].similarity) {
1281 /* Clear previous best similarity */
1282 if (similarity_ours[i].similarity > 0)
1283 similarity_ours[similarity_ours[i].other_idx].similarity = 0;
1284
1285 if (similarity_ours[j].similarity > 0)
1286 similarity_ours[similarity_ours[j].other_idx].similarity = 0;
1287
1288 similarity_ours[i].similarity = similarity;
1289 similarity_ours[i].other_idx = j;
1290
1291 similarity_ours[j].similarity = similarity;
1292 similarity_ours[j].other_idx = i;
1293 }
1294 }
1295
1296 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_tgt->their_entry) &&
1297 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict_src->their_entry)) {
1298 similarity = index_entry_similarity_inexact(repo, &conflict_src->ancestor_entry, i, &conflict_tgt->their_entry, their_idx, cache, opts);
1299
1300 if (similarity > similarity_theirs[i].similarity &&
1301 similarity > similarity_theirs[j].similarity) {
1302 /* Clear previous best similarity */
1303 if (similarity_theirs[i].similarity > 0)
1304 similarity_theirs[similarity_theirs[i].other_idx].similarity = 0;
1305
1306 if (similarity_theirs[j].similarity > 0)
1307 similarity_theirs[similarity_theirs[j].other_idx].similarity = 0;
1308
1309 similarity_theirs[i].similarity = similarity;
1310 similarity_theirs[i].other_idx = j;
1311
1312 similarity_theirs[j].similarity = similarity;
1313 similarity_theirs[j].other_idx = i;
1314 }
1315 }
1316 }
1317 }
1318
1319 return 0;
1320 }
1321
1322 /*
1323 * Rename conflicts:
1324 *
1325 * Ancestor Ours Theirs
1326 *
1327 * 0a A A A No rename
1328 * b A A* A No rename (ours was rewritten)
1329 * c A A A* No rename (theirs rewritten)
1330 * 1a A A B[A] Rename or rename/edit
1331 * b A B[A] A (automergeable)
1332 * 2 A B[A] B[A] Both renamed (automergeable)
1333 * 3a A B[A] Rename/delete
1334 * b A B[A] (same)
1335 * 4a A B[A] B Rename/add [B~ours B~theirs]
1336 * b A B B[A] (same)
1337 * 5 A B[A] C[A] Both renamed ("1 -> 2")
1338 * 6 A C[A] Both renamed ("2 -> 1")
1339 * B C[B] [C~ours C~theirs] (automergeable)
1340 */
1341 static void merge_diff_mark_rename_conflict(
1342 git_merge_diff_list *diff_list,
1343 struct merge_diff_similarity *similarity_ours,
1344 bool ours_renamed,
1345 size_t ours_source_idx,
1346 struct merge_diff_similarity *similarity_theirs,
1347 bool theirs_renamed,
1348 size_t theirs_source_idx,
1349 git_merge_diff *target,
1350 const git_merge_options *opts)
1351 {
1352 git_merge_diff *ours_source = NULL, *theirs_source = NULL;
1353
1354 if (ours_renamed)
1355 ours_source = diff_list->conflicts.contents[ours_source_idx];
1356
1357 if (theirs_renamed)
1358 theirs_source = diff_list->conflicts.contents[theirs_source_idx];
1359
1360 /* Detect 2->1 conflicts */
1361 if (ours_renamed && theirs_renamed) {
1362 /* Both renamed to the same target name. */
1363 if (ours_source_idx == theirs_source_idx)
1364 ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED;
1365 else {
1366 ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1;
1367 theirs_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1;
1368 }
1369 } else if (ours_renamed) {
1370 /* If our source was also renamed in theirs, this is a 1->2 */
1371 if (similarity_theirs[ours_source_idx].similarity >= opts->rename_threshold)
1372 ours_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
1373
1374 else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry)) {
1375 ours_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
1376 target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
1377 }
1378
1379 else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(ours_source->their_entry))
1380 ours_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
1381
1382 else if (ours_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
1383 ours_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
1384 } else if (theirs_renamed) {
1385 /* If their source was also renamed in ours, this is a 1->2 */
1386 if (similarity_ours[theirs_source_idx].similarity >= opts->rename_threshold)
1387 theirs_source->type = GIT_MERGE_DIFF_BOTH_RENAMED_1_TO_2;
1388
1389 else if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry)) {
1390 theirs_source->type = GIT_MERGE_DIFF_RENAMED_ADDED;
1391 target->type = GIT_MERGE_DIFF_RENAMED_ADDED;
1392 }
1393
1394 else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(theirs_source->our_entry))
1395 theirs_source->type = GIT_MERGE_DIFF_RENAMED_DELETED;
1396
1397 else if (theirs_source->type == GIT_MERGE_DIFF_MODIFIED_DELETED)
1398 theirs_source->type = GIT_MERGE_DIFF_RENAMED_MODIFIED;
1399 }
1400 }
1401
1402 GIT_INLINE(void) merge_diff_coalesce_rename(
1403 git_index_entry *source_entry,
1404 git_delta_t *source_status,
1405 git_index_entry *target_entry,
1406 git_delta_t *target_status)
1407 {
1408 /* Coalesce the rename target into the rename source. */
1409 memcpy(source_entry, target_entry, sizeof(git_index_entry));
1410 *source_status = GIT_DELTA_RENAMED;
1411
1412 memset(target_entry, 0x0, sizeof(git_index_entry));
1413 *target_status = GIT_DELTA_UNMODIFIED;
1414 }
1415
1416 static void merge_diff_list_coalesce_renames(
1417 git_merge_diff_list *diff_list,
1418 struct merge_diff_similarity *similarity_ours,
1419 struct merge_diff_similarity *similarity_theirs,
1420 const git_merge_options *opts)
1421 {
1422 size_t i;
1423 bool ours_renamed = 0, theirs_renamed = 0;
1424 size_t ours_source_idx = 0, theirs_source_idx = 0;
1425 git_merge_diff *ours_source, *theirs_source, *target;
1426
1427 for (i = 0; i < diff_list->conflicts.length; i++) {
1428 target = diff_list->conflicts.contents[i];
1429
1430 ours_renamed = 0;
1431 theirs_renamed = 0;
1432
1433 if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->our_entry) &&
1434 similarity_ours[i].similarity >= opts->rename_threshold) {
1435 ours_source_idx = similarity_ours[i].other_idx;
1436
1437 ours_source = diff_list->conflicts.contents[ours_source_idx];
1438
1439 merge_diff_coalesce_rename(
1440 &ours_source->our_entry,
1441 &ours_source->our_status,
1442 &target->our_entry,
1443 &target->our_status);
1444
1445 similarity_ours[ours_source_idx].similarity = 0;
1446 similarity_ours[i].similarity = 0;
1447
1448 ours_renamed = 1;
1449 }
1450
1451 /* insufficient to determine direction */
1452 if (GIT_MERGE_INDEX_ENTRY_EXISTS(target->their_entry) &&
1453 similarity_theirs[i].similarity >= opts->rename_threshold) {
1454 theirs_source_idx = similarity_theirs[i].other_idx;
1455
1456 theirs_source = diff_list->conflicts.contents[theirs_source_idx];
1457
1458 merge_diff_coalesce_rename(
1459 &theirs_source->their_entry,
1460 &theirs_source->their_status,
1461 &target->their_entry,
1462 &target->their_status);
1463
1464 similarity_theirs[theirs_source_idx].similarity = 0;
1465 similarity_theirs[i].similarity = 0;
1466
1467 theirs_renamed = 1;
1468 }
1469
1470 merge_diff_mark_rename_conflict(diff_list,
1471 similarity_ours, ours_renamed, ours_source_idx,
1472 similarity_theirs, theirs_renamed, theirs_source_idx,
1473 target, opts);
1474 }
1475 }
1476
1477 static int merge_diff_empty(const git_vector *conflicts, size_t idx, void *p)
1478 {
1479 git_merge_diff *conflict = conflicts->contents[idx];
1480
1481 GIT_UNUSED(p);
1482
1483 return (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) &&
1484 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) &&
1485 !GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry));
1486 }
1487
1488 static void merge_diff_list_count_candidates(
1489 git_merge_diff_list *diff_list,
1490 size_t *src_count,
1491 size_t *tgt_count)
1492 {
1493 git_merge_diff *entry;
1494 size_t i;
1495
1496 *src_count = 0;
1497 *tgt_count = 0;
1498
1499 git_vector_foreach(&diff_list->conflicts, i, entry) {
1500 if (GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry) &&
1501 (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->our_entry) ||
1502 !GIT_MERGE_INDEX_ENTRY_EXISTS(entry->their_entry)))
1503 (*src_count)++;
1504 else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry))
1505 (*tgt_count)++;
1506 }
1507 }
1508
1509 int git_merge_diff_list__find_renames(
1510 git_repository *repo,
1511 git_merge_diff_list *diff_list,
1512 const git_merge_options *opts)
1513 {
1514 struct merge_diff_similarity *similarity_ours, *similarity_theirs;
1515 void **cache = NULL;
1516 size_t cache_size = 0;
1517 size_t src_count, tgt_count, i;
1518 int error = 0;
1519
1520 assert(diff_list && opts);
1521
1522 if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0)
1523 return 0;
1524
1525 similarity_ours = git__calloc(diff_list->conflicts.length,
1526 sizeof(struct merge_diff_similarity));
1527 GIT_ERROR_CHECK_ALLOC(similarity_ours);
1528
1529 similarity_theirs = git__calloc(diff_list->conflicts.length,
1530 sizeof(struct merge_diff_similarity));
1531 GIT_ERROR_CHECK_ALLOC(similarity_theirs);
1532
1533 /* Calculate similarity between items that were deleted from the ancestor
1534 * and added in the other branch.
1535 */
1536 if ((error = merge_diff_mark_similarity_exact(diff_list, similarity_ours, similarity_theirs)) < 0)
1537 goto done;
1538
1539 if (opts->rename_threshold < 100 && diff_list->conflicts.length <= opts->target_limit) {
1540 GIT_ERROR_CHECK_ALLOC_MULTIPLY(&cache_size, diff_list->conflicts.length, 3);
1541 cache = git__calloc(cache_size, sizeof(void *));
1542 GIT_ERROR_CHECK_ALLOC(cache);
1543
1544 merge_diff_list_count_candidates(diff_list, &src_count, &tgt_count);
1545
1546 if (src_count > opts->target_limit || tgt_count > opts->target_limit) {
1547 /* TODO: report! */
1548 } else {
1549 if ((error = merge_diff_mark_similarity_inexact(
1550 repo, diff_list, similarity_ours, similarity_theirs, cache, opts)) < 0)
1551 goto done;
1552 }
1553 }
1554
1555 /* For entries that are appropriately similar, merge the new name's entry
1556 * into the old name.
1557 */
1558 merge_diff_list_coalesce_renames(diff_list, similarity_ours, similarity_theirs, opts);
1559
1560 /* And remove any entries that were merged and are now empty. */
1561 git_vector_remove_matching(&diff_list->conflicts, merge_diff_empty, NULL);
1562
1563 done:
1564 if (cache != NULL) {
1565 for (i = 0; i < cache_size; ++i) {
1566 if (cache[i] != NULL && cache[i] != &cache_invalid_marker)
1567 opts->metric->free_signature(cache[i], opts->metric->payload);
1568 }
1569
1570 git__free(cache);
1571 }
1572
1573 git__free(similarity_ours);
1574 git__free(similarity_theirs);
1575
1576 return error;
1577 }
1578
1579 /* Directory/file conflict handling */
1580
1581 GIT_INLINE(const char *) merge_diff_path(
1582 const git_merge_diff *conflict)
1583 {
1584 if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry))
1585 return conflict->ancestor_entry.path;
1586 else if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry))
1587 return conflict->our_entry.path;
1588 else if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
1589 return conflict->their_entry.path;
1590
1591 return NULL;
1592 }
1593
1594 GIT_INLINE(bool) merge_diff_any_side_added_or_modified(
1595 const git_merge_diff *conflict)
1596 {
1597 if (conflict->our_status == GIT_DELTA_ADDED ||
1598 conflict->our_status == GIT_DELTA_MODIFIED ||
1599 conflict->their_status == GIT_DELTA_ADDED ||
1600 conflict->their_status == GIT_DELTA_MODIFIED)
1601 return true;
1602
1603 return false;
1604 }
1605
1606 GIT_INLINE(bool) path_is_prefixed(const char *parent, const char *child)
1607 {
1608 size_t child_len = strlen(child);
1609 size_t parent_len = strlen(parent);
1610
1611 if (child_len < parent_len ||
1612 strncmp(parent, child, parent_len) != 0)
1613 return 0;
1614
1615 return (child[parent_len] == '/');
1616 }
1617
1618 GIT_INLINE(int) merge_diff_detect_df_conflict(
1619 struct merge_diff_df_data *df_data,
1620 git_merge_diff *conflict)
1621 {
1622 const char *cur_path = merge_diff_path(conflict);
1623
1624 /* Determine if this is a D/F conflict or the child of one */
1625 if (df_data->df_path &&
1626 path_is_prefixed(df_data->df_path, cur_path))
1627 conflict->type = GIT_MERGE_DIFF_DF_CHILD;
1628 else if(df_data->df_path)
1629 df_data->df_path = NULL;
1630 else if (df_data->prev_path &&
1631 merge_diff_any_side_added_or_modified(df_data->prev_conflict) &&
1632 merge_diff_any_side_added_or_modified(conflict) &&
1633 path_is_prefixed(df_data->prev_path, cur_path)) {
1634 conflict->type = GIT_MERGE_DIFF_DF_CHILD;
1635
1636 df_data->prev_conflict->type = GIT_MERGE_DIFF_DIRECTORY_FILE;
1637 df_data->df_path = df_data->prev_path;
1638 }
1639
1640 df_data->prev_path = cur_path;
1641 df_data->prev_conflict = conflict;
1642
1643 return 0;
1644 }
1645
1646 /* Conflict handling */
1647
1648 GIT_INLINE(int) merge_diff_detect_type(
1649 git_merge_diff *conflict)
1650 {
1651 if (conflict->our_status == GIT_DELTA_ADDED &&
1652 conflict->their_status == GIT_DELTA_ADDED)
1653 conflict->type = GIT_MERGE_DIFF_BOTH_ADDED;
1654 else if (conflict->our_status == GIT_DELTA_MODIFIED &&
1655 conflict->their_status == GIT_DELTA_MODIFIED)
1656 conflict->type = GIT_MERGE_DIFF_BOTH_MODIFIED;
1657 else if (conflict->our_status == GIT_DELTA_DELETED &&
1658 conflict->their_status == GIT_DELTA_DELETED)
1659 conflict->type = GIT_MERGE_DIFF_BOTH_DELETED;
1660 else if (conflict->our_status == GIT_DELTA_MODIFIED &&
1661 conflict->their_status == GIT_DELTA_DELETED)
1662 conflict->type = GIT_MERGE_DIFF_MODIFIED_DELETED;
1663 else if (conflict->our_status == GIT_DELTA_DELETED &&
1664 conflict->their_status == GIT_DELTA_MODIFIED)
1665 conflict->type = GIT_MERGE_DIFF_MODIFIED_DELETED;
1666 else
1667 conflict->type = GIT_MERGE_DIFF_NONE;
1668
1669 return 0;
1670 }
1671
1672 GIT_INLINE(int) index_entry_dup_pool(
1673 git_index_entry *out,
1674 git_pool *pool,
1675 const git_index_entry *src)
1676 {
1677 if (src != NULL) {
1678 memcpy(out, src, sizeof(git_index_entry));
1679 if ((out->path = git_pool_strdup(pool, src->path)) == NULL)
1680 return -1;
1681 }
1682
1683 return 0;
1684 }
1685
1686 GIT_INLINE(int) merge_delta_type_from_index_entries(
1687 const git_index_entry *ancestor,
1688 const git_index_entry *other)
1689 {
1690 if (ancestor == NULL && other == NULL)
1691 return GIT_DELTA_UNMODIFIED;
1692 else if (ancestor == NULL && other != NULL)
1693 return GIT_DELTA_ADDED;
1694 else if (ancestor != NULL && other == NULL)
1695 return GIT_DELTA_DELETED;
1696 else if (S_ISDIR(ancestor->mode) ^ S_ISDIR(other->mode))
1697 return GIT_DELTA_TYPECHANGE;
1698 else if(S_ISLNK(ancestor->mode) ^ S_ISLNK(other->mode))
1699 return GIT_DELTA_TYPECHANGE;
1700 else if (git_oid__cmp(&ancestor->id, &other->id) ||
1701 ancestor->mode != other->mode)
1702 return GIT_DELTA_MODIFIED;
1703
1704 return GIT_DELTA_UNMODIFIED;
1705 }
1706
1707 static git_merge_diff *merge_diff_from_index_entries(
1708 git_merge_diff_list *diff_list,
1709 const git_index_entry **entries)
1710 {
1711 git_merge_diff *conflict;
1712 git_pool *pool = &diff_list->pool;
1713
1714 if ((conflict = git_pool_mallocz(pool, sizeof(git_merge_diff))) == NULL)
1715 return NULL;
1716
1717 if (index_entry_dup_pool(&conflict->ancestor_entry, pool, entries[TREE_IDX_ANCESTOR]) < 0 ||
1718 index_entry_dup_pool(&conflict->our_entry, pool, entries[TREE_IDX_OURS]) < 0 ||
1719 index_entry_dup_pool(&conflict->their_entry, pool, entries[TREE_IDX_THEIRS]) < 0)
1720 return NULL;
1721
1722 conflict->our_status = merge_delta_type_from_index_entries(
1723 entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_OURS]);
1724 conflict->their_status = merge_delta_type_from_index_entries(
1725 entries[TREE_IDX_ANCESTOR], entries[TREE_IDX_THEIRS]);
1726
1727 return conflict;
1728 }
1729
1730 /* Merge trees */
1731
1732 static int merge_diff_list_insert_conflict(
1733 git_merge_diff_list *diff_list,
1734 struct merge_diff_df_data *merge_df_data,
1735 const git_index_entry *tree_items[3])
1736 {
1737 git_merge_diff *conflict;
1738
1739 if ((conflict = merge_diff_from_index_entries(diff_list, tree_items)) == NULL ||
1740 merge_diff_detect_type(conflict) < 0 ||
1741 merge_diff_detect_df_conflict(merge_df_data, conflict) < 0 ||
1742 git_vector_insert(&diff_list->conflicts, conflict) < 0)
1743 return -1;
1744
1745 return 0;
1746 }
1747
1748 static int merge_diff_list_insert_unmodified(
1749 git_merge_diff_list *diff_list,
1750 const git_index_entry *tree_items[3])
1751 {
1752 int error = 0;
1753 git_index_entry *entry;
1754
1755 entry = git_pool_malloc(&diff_list->pool, sizeof(git_index_entry));
1756 GIT_ERROR_CHECK_ALLOC(entry);
1757
1758 if ((error = index_entry_dup_pool(entry, &diff_list->pool, tree_items[0])) >= 0)
1759 error = git_vector_insert(&diff_list->staged, entry);
1760
1761 return error;
1762 }
1763
1764 struct merge_diff_find_data {
1765 git_merge_diff_list *diff_list;
1766 struct merge_diff_df_data df_data;
1767 };
1768
1769 static int queue_difference(const git_index_entry **entries, void *data)
1770 {
1771 struct merge_diff_find_data *find_data = data;
1772 bool item_modified = false;
1773 size_t i;
1774
1775 if (!entries[0] || !entries[1] || !entries[2]) {
1776 item_modified = true;
1777 } else {
1778 for (i = 1; i < 3; i++) {
1779 if (index_entry_cmp(entries[0], entries[i]) != 0) {
1780 item_modified = true;
1781 break;
1782 }
1783 }
1784 }
1785
1786 return item_modified ?
1787 merge_diff_list_insert_conflict(
1788 find_data->diff_list, &find_data->df_data, entries) :
1789 merge_diff_list_insert_unmodified(find_data->diff_list, entries);
1790 }
1791
1792 int git_merge_diff_list__find_differences(
1793 git_merge_diff_list *diff_list,
1794 git_iterator *ancestor_iter,
1795 git_iterator *our_iter,
1796 git_iterator *their_iter)
1797 {
1798 git_iterator *iterators[3] = { ancestor_iter, our_iter, their_iter };
1799 struct merge_diff_find_data find_data = { diff_list };
1800
1801 return git_iterator_walk(iterators, 3, queue_difference, &find_data);
1802 }
1803
1804 git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo)
1805 {
1806 git_merge_diff_list *diff_list = git__calloc(1, sizeof(git_merge_diff_list));
1807
1808 if (diff_list == NULL)
1809 return NULL;
1810
1811 diff_list->repo = repo;
1812
1813
1814 if (git_pool_init(&diff_list->pool, 1) < 0 ||
1815 git_vector_init(&diff_list->staged, 0, NULL) < 0 ||
1816 git_vector_init(&diff_list->conflicts, 0, NULL) < 0 ||
1817 git_vector_init(&diff_list->resolved, 0, NULL) < 0) {
1818 git_merge_diff_list__free(diff_list);
1819 return NULL;
1820 }
1821
1822 return diff_list;
1823 }
1824
1825 void git_merge_diff_list__free(git_merge_diff_list *diff_list)
1826 {
1827 if (!diff_list)
1828 return;
1829
1830 git_vector_free(&diff_list->staged);
1831 git_vector_free(&diff_list->conflicts);
1832 git_vector_free(&diff_list->resolved);
1833 git_pool_clear(&diff_list->pool);
1834 git__free(diff_list);
1835 }
1836
1837 static int merge_normalize_opts(
1838 git_repository *repo,
1839 git_merge_options *opts,
1840 const git_merge_options *given)
1841 {
1842 git_config *cfg = NULL;
1843 git_config_entry *entry = NULL;
1844 int error = 0;
1845
1846 assert(repo && opts);
1847
1848 if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
1849 return error;
1850
1851 if (given != NULL) {
1852 memcpy(opts, given, sizeof(git_merge_options));
1853 } else {
1854 git_merge_options init = GIT_MERGE_OPTIONS_INIT;
1855 memcpy(opts, &init, sizeof(init));
1856 }
1857
1858 if ((opts->flags & GIT_MERGE_FIND_RENAMES) && !opts->rename_threshold)
1859 opts->rename_threshold = GIT_MERGE_DEFAULT_RENAME_THRESHOLD;
1860
1861 if (given && given->default_driver) {
1862 opts->default_driver = git__strdup(given->default_driver);
1863 GIT_ERROR_CHECK_ALLOC(opts->default_driver);
1864 } else {
1865 error = git_config_get_entry(&entry, cfg, "merge.default");
1866
1867 if (error == 0) {
1868 opts->default_driver = git__strdup(entry->value);
1869 GIT_ERROR_CHECK_ALLOC(opts->default_driver);
1870 } else if (error == GIT_ENOTFOUND) {
1871 error = 0;
1872 } else {
1873 goto done;
1874 }
1875 }
1876
1877 if (!opts->target_limit) {
1878 int limit = git_config__get_int_force(cfg, "merge.renamelimit", 0);
1879
1880 if (!limit)
1881 limit = git_config__get_int_force(cfg, "diff.renamelimit", 0);
1882
1883 opts->target_limit = (limit <= 0) ?
1884 GIT_MERGE_DEFAULT_TARGET_LIMIT : (unsigned int)limit;
1885 }
1886
1887 /* assign the internal metric with whitespace flag as payload */
1888 if (!opts->metric) {
1889 opts->metric = git__malloc(sizeof(git_diff_similarity_metric));
1890 GIT_ERROR_CHECK_ALLOC(opts->metric);
1891
1892 opts->metric->file_signature = git_diff_find_similar__hashsig_for_file;
1893 opts->metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
1894 opts->metric->free_signature = git_diff_find_similar__hashsig_free;
1895 opts->metric->similarity = git_diff_find_similar__calc_similarity;
1896 opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
1897 }
1898
1899 done:
1900 git_config_entry_free(entry);
1901 return error;
1902 }
1903
1904
1905 static int merge_index_insert_reuc(
1906 git_index *index,
1907 size_t idx,
1908 const git_index_entry *entry)
1909 {
1910 const git_index_reuc_entry *reuc;
1911 int mode[3] = { 0, 0, 0 };
1912 git_oid const *oid[3] = { NULL, NULL, NULL };
1913 size_t i;
1914
1915 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(*entry))
1916 return 0;
1917
1918 if ((reuc = git_index_reuc_get_bypath(index, entry->path)) != NULL) {
1919 for (i = 0; i < 3; i++) {
1920 mode[i] = reuc->mode[i];
1921 oid[i] = &reuc->oid[i];
1922 }
1923 }
1924
1925 mode[idx] = entry->mode;
1926 oid[idx] = &entry->id;
1927
1928 return git_index_reuc_add(index, entry->path,
1929 mode[0], oid[0], mode[1], oid[1], mode[2], oid[2]);
1930 }
1931
1932 static int index_update_reuc(git_index *index, git_merge_diff_list *diff_list)
1933 {
1934 int error;
1935 size_t i;
1936 git_merge_diff *conflict;
1937
1938 /* Add each entry in the resolved conflict to the REUC independently, since
1939 * the paths may differ due to renames. */
1940 git_vector_foreach(&diff_list->resolved, i, conflict) {
1941 const git_index_entry *ancestor =
1942 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
1943 &conflict->ancestor_entry : NULL;
1944
1945 const git_index_entry *ours =
1946 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
1947 &conflict->our_entry : NULL;
1948
1949 const git_index_entry *theirs =
1950 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
1951 &conflict->their_entry : NULL;
1952
1953 if (ancestor != NULL &&
1954 (error = merge_index_insert_reuc(index, TREE_IDX_ANCESTOR, ancestor)) < 0)
1955 return error;
1956
1957 if (ours != NULL &&
1958 (error = merge_index_insert_reuc(index, TREE_IDX_OURS, ours)) < 0)
1959 return error;
1960
1961 if (theirs != NULL &&
1962 (error = merge_index_insert_reuc(index, TREE_IDX_THEIRS, theirs)) < 0)
1963 return error;
1964 }
1965
1966 return 0;
1967 }
1968
1969 static int index_from_diff_list(git_index **out,
1970 git_merge_diff_list *diff_list, bool skip_reuc)
1971 {
1972 git_index *index;
1973 size_t i;
1974 git_merge_diff *conflict;
1975 int error = 0;
1976
1977 *out = NULL;
1978
1979 if ((error = git_index_new(&index)) < 0)
1980 return error;
1981
1982 if ((error = git_index__fill(index, &diff_list->staged)) < 0)
1983 goto on_error;
1984
1985 git_vector_foreach(&diff_list->conflicts, i, conflict) {
1986 const git_index_entry *ancestor =
1987 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
1988 &conflict->ancestor_entry : NULL;
1989
1990 const git_index_entry *ours =
1991 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
1992 &conflict->our_entry : NULL;
1993
1994 const git_index_entry *theirs =
1995 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
1996 &conflict->their_entry : NULL;
1997
1998 if ((error = git_index_conflict_add(index, ancestor, ours, theirs)) < 0)
1999 goto on_error;
2000 }
2001
2002 /* Add each rename entry to the rename portion of the index. */
2003 git_vector_foreach(&diff_list->conflicts, i, conflict) {
2004 const char *ancestor_path, *our_path, *their_path;
2005
2006 if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry))
2007 continue;
2008
2009 ancestor_path = conflict->ancestor_entry.path;
2010
2011 our_path =
2012 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
2013 conflict->our_entry.path : NULL;
2014
2015 their_path =
2016 GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
2017 conflict->their_entry.path : NULL;
2018
2019 if ((our_path && strcmp(ancestor_path, our_path) != 0) ||
2020 (their_path && strcmp(ancestor_path, their_path) != 0)) {
2021 if ((error = git_index_name_add(index, ancestor_path, our_path, their_path)) < 0)
2022 goto on_error;
2023 }
2024 }
2025
2026 if (!skip_reuc) {
2027 if ((error = index_update_reuc(index, diff_list)) < 0)
2028 goto on_error;
2029 }
2030
2031 *out = index;
2032 return 0;
2033
2034 on_error:
2035 git_index_free(index);
2036 return error;
2037 }
2038
2039 static git_iterator *iterator_given_or_empty(git_iterator **empty, git_iterator *given)
2040 {
2041 git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT;
2042
2043 if (given)
2044 return given;
2045
2046 opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2047
2048 if (git_iterator_for_nothing(empty, &opts) < 0)
2049 return NULL;
2050
2051 return *empty;
2052 }
2053
2054 int git_merge__iterators(
2055 git_index **out,
2056 git_repository *repo,
2057 git_iterator *ancestor_iter,
2058 git_iterator *our_iter,
2059 git_iterator *theirs_iter,
2060 const git_merge_options *given_opts)
2061 {
2062 git_iterator *empty_ancestor = NULL,
2063 *empty_ours = NULL,
2064 *empty_theirs = NULL;
2065 git_merge_diff_list *diff_list;
2066 git_merge_options opts;
2067 git_merge_file_options file_opts = GIT_MERGE_FILE_OPTIONS_INIT;
2068 git_merge_diff *conflict;
2069 git_vector changes;
2070 size_t i;
2071 int error = 0;
2072
2073 assert(out && repo);
2074
2075 *out = NULL;
2076
2077 GIT_ERROR_CHECK_VERSION(
2078 given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options");
2079
2080 if ((error = merge_normalize_opts(repo, &opts, given_opts)) < 0)
2081 return error;
2082
2083 file_opts.favor = opts.file_favor;
2084 file_opts.flags = opts.file_flags;
2085
2086 /* use the git-inspired labels when virtual base building */
2087 if (opts.flags & GIT_MERGE__VIRTUAL_BASE) {
2088 file_opts.ancestor_label = "merged common ancestors";
2089 file_opts.our_label = "Temporary merge branch 1";
2090 file_opts.their_label = "Temporary merge branch 2";
2091 file_opts.flags |= GIT_MERGE_FILE_FAVOR__CONFLICTED;
2092 file_opts.marker_size = GIT_MERGE_CONFLICT_MARKER_SIZE + 2;
2093 }
2094
2095 diff_list = git_merge_diff_list__alloc(repo);
2096 GIT_ERROR_CHECK_ALLOC(diff_list);
2097
2098 ancestor_iter = iterator_given_or_empty(&empty_ancestor, ancestor_iter);
2099 our_iter = iterator_given_or_empty(&empty_ours, our_iter);
2100 theirs_iter = iterator_given_or_empty(&empty_theirs, theirs_iter);
2101
2102 if ((error = git_merge_diff_list__find_differences(
2103 diff_list, ancestor_iter, our_iter, theirs_iter)) < 0 ||
2104 (error = git_merge_diff_list__find_renames(repo, diff_list, &opts)) < 0)
2105 goto done;
2106
2107 memcpy(&changes, &diff_list->conflicts, sizeof(git_vector));
2108 git_vector_clear(&diff_list->conflicts);
2109
2110 git_vector_foreach(&changes, i, conflict) {
2111 int resolved = 0;
2112
2113 if ((error = merge_conflict_resolve(
2114 &resolved, diff_list, conflict, &opts, &file_opts)) < 0)
2115 goto done;
2116
2117 if (!resolved) {
2118 if ((opts.flags & GIT_MERGE_FAIL_ON_CONFLICT)) {
2119 git_error_set(GIT_ERROR_MERGE, "merge conflicts exist");
2120 error = GIT_EMERGECONFLICT;
2121 goto done;
2122 }
2123
2124 git_vector_insert(&diff_list->conflicts, conflict);
2125 }
2126 }
2127
2128 error = index_from_diff_list(out, diff_list,
2129 (opts.flags & GIT_MERGE_SKIP_REUC));
2130
2131 done:
2132 if (!given_opts || !given_opts->metric)
2133 git__free(opts.metric);
2134
2135 git__free((char *)opts.default_driver);
2136
2137 git_merge_diff_list__free(diff_list);
2138 git_iterator_free(empty_ancestor);
2139 git_iterator_free(empty_ours);
2140 git_iterator_free(empty_theirs);
2141
2142 return error;
2143 }
2144
2145 int git_merge_trees(
2146 git_index **out,
2147 git_repository *repo,
2148 const git_tree *ancestor_tree,
2149 const git_tree *our_tree,
2150 const git_tree *their_tree,
2151 const git_merge_options *merge_opts)
2152 {
2153 git_iterator *ancestor_iter = NULL, *our_iter = NULL, *their_iter = NULL;
2154 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
2155 int error;
2156
2157 assert(out && repo);
2158
2159 /* if one side is treesame to the ancestor, take the other side */
2160 if (ancestor_tree && merge_opts && (merge_opts->flags & GIT_MERGE_SKIP_REUC)) {
2161 const git_tree *result = NULL;
2162 const git_oid *ancestor_tree_id = git_tree_id(ancestor_tree);
2163
2164 if (our_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(our_tree)))
2165 result = their_tree;
2166 else if (their_tree && !git_oid_cmp(ancestor_tree_id, git_tree_id(their_tree)))
2167 result = our_tree;
2168
2169 if (result) {
2170 if ((error = git_index_new(out)) == 0)
2171 error = git_index_read_tree(*out, result);
2172
2173 return error;
2174 }
2175 }
2176
2177 iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2178
2179 if ((error = git_iterator_for_tree(
2180 &ancestor_iter, (git_tree *)ancestor_tree, &iter_opts)) < 0 ||
2181 (error = git_iterator_for_tree(
2182 &our_iter, (git_tree *)our_tree, &iter_opts)) < 0 ||
2183 (error = git_iterator_for_tree(
2184 &their_iter, (git_tree *)their_tree, &iter_opts)) < 0)
2185 goto done;
2186
2187 error = git_merge__iterators(
2188 out, repo, ancestor_iter, our_iter, their_iter, merge_opts);
2189
2190 done:
2191 git_iterator_free(ancestor_iter);
2192 git_iterator_free(our_iter);
2193 git_iterator_free(their_iter);
2194
2195 return error;
2196 }
2197
2198 static int merge_annotated_commits(
2199 git_index **index_out,
2200 git_annotated_commit **base_out,
2201 git_repository *repo,
2202 git_annotated_commit *our_commit,
2203 git_annotated_commit *their_commit,
2204 size_t recursion_level,
2205 const git_merge_options *opts);
2206
2207 GIT_INLINE(int) insert_head_ids(
2208 git_array_oid_t *ids,
2209 const git_annotated_commit *annotated_commit)
2210 {
2211 git_oid *id;
2212 size_t i;
2213
2214 if (annotated_commit->type == GIT_ANNOTATED_COMMIT_REAL) {
2215 id = git_array_alloc(*ids);
2216 GIT_ERROR_CHECK_ALLOC(id);
2217
2218 git_oid_cpy(id, git_commit_id(annotated_commit->commit));
2219 } else {
2220 for (i = 0; i < annotated_commit->parents.size; i++) {
2221 id = git_array_alloc(*ids);
2222 GIT_ERROR_CHECK_ALLOC(id);
2223
2224 git_oid_cpy(id, &annotated_commit->parents.ptr[i]);
2225 }
2226 }
2227
2228 return 0;
2229 }
2230
2231 static int create_virtual_base(
2232 git_annotated_commit **out,
2233 git_repository *repo,
2234 git_annotated_commit *one,
2235 git_annotated_commit *two,
2236 const git_merge_options *opts,
2237 size_t recursion_level)
2238 {
2239 git_annotated_commit *result = NULL;
2240 git_index *index = NULL;
2241 git_merge_options virtual_opts = GIT_MERGE_OPTIONS_INIT;
2242
2243 /* Conflicts in the merge base creation do not propagate to conflicts
2244 * in the result; the conflicted base will act as the common ancestor.
2245 */
2246 if (opts)
2247 memcpy(&virtual_opts, opts, sizeof(git_merge_options));
2248
2249 virtual_opts.flags &= ~GIT_MERGE_FAIL_ON_CONFLICT;
2250 virtual_opts.flags |= GIT_MERGE__VIRTUAL_BASE;
2251
2252 if ((merge_annotated_commits(&index, NULL, repo, one, two,
2253 recursion_level + 1, &virtual_opts)) < 0)
2254 return -1;
2255
2256 result = git__calloc(1, sizeof(git_annotated_commit));
2257 GIT_ERROR_CHECK_ALLOC(result);
2258 result->type = GIT_ANNOTATED_COMMIT_VIRTUAL;
2259 result->index = index;
2260
2261 insert_head_ids(&result->parents, one);
2262 insert_head_ids(&result->parents, two);
2263
2264 *out = result;
2265 return 0;
2266 }
2267
2268 static int compute_base(
2269 git_annotated_commit **out,
2270 git_repository *repo,
2271 const git_annotated_commit *one,
2272 const git_annotated_commit *two,
2273 const git_merge_options *given_opts,
2274 size_t recursion_level)
2275 {
2276 git_array_oid_t head_ids = GIT_ARRAY_INIT;
2277 git_oidarray bases = {0};
2278 git_annotated_commit *base = NULL, *other = NULL, *new_base = NULL;
2279 git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
2280 size_t i, base_count;
2281 int error;
2282
2283 *out = NULL;
2284
2285 if (given_opts)
2286 memcpy(&opts, given_opts, sizeof(git_merge_options));
2287
2288 /* With more than two commits, merge_bases_many finds the base of
2289 * the first commit and a hypothetical merge of the others. Since
2290 * "one" may itself be a virtual commit, which insert_head_ids
2291 * substitutes multiple ancestors for, it needs to be added
2292 * after "two" which is always a single real commit.
2293 */
2294 if ((error = insert_head_ids(&head_ids, two)) < 0 ||
2295 (error = insert_head_ids(&head_ids, one)) < 0 ||
2296 (error = git_merge_bases_many(&bases, repo,
2297 head_ids.size, head_ids.ptr)) < 0)
2298 goto done;
2299
2300 base_count = (opts.flags & GIT_MERGE_NO_RECURSIVE) ? 0 : bases.count;
2301
2302 if (base_count)
2303 git_oidarray__reverse(&bases);
2304
2305 if ((error = git_annotated_commit_lookup(&base, repo, &bases.ids[0])) < 0)
2306 goto done;
2307
2308 for (i = 1; i < base_count; i++) {
2309 recursion_level++;
2310
2311 if (opts.recursion_limit && recursion_level > opts.recursion_limit)
2312 break;
2313
2314 if ((error = git_annotated_commit_lookup(&other, repo,
2315 &bases.ids[i])) < 0 ||
2316 (error = create_virtual_base(&new_base, repo, base, other, &opts,
2317 recursion_level)) < 0)
2318 goto done;
2319
2320 git_annotated_commit_free(base);
2321 git_annotated_commit_free(other);
2322
2323 base = new_base;
2324 new_base = NULL;
2325 other = NULL;
2326 }
2327
2328 done:
2329 if (error == 0)
2330 *out = base;
2331 else
2332 git_annotated_commit_free(base);
2333
2334 git_annotated_commit_free(other);
2335 git_annotated_commit_free(new_base);
2336 git_oidarray_free(&bases);
2337 git_array_clear(head_ids);
2338 return error;
2339 }
2340
2341 static int iterator_for_annotated_commit(
2342 git_iterator **out,
2343 git_annotated_commit *commit)
2344 {
2345 git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT;
2346 int error;
2347
2348 opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2349
2350 if (commit == NULL) {
2351 error = git_iterator_for_nothing(out, &opts);
2352 } else if (commit->type == GIT_ANNOTATED_COMMIT_VIRTUAL) {
2353 error = git_iterator_for_index(out, git_index_owner(commit->index), commit->index, &opts);
2354 } else {
2355 if (!commit->tree &&
2356 (error = git_commit_tree(&commit->tree, commit->commit)) < 0)
2357 goto done;
2358
2359 error = git_iterator_for_tree(out, commit->tree, &opts);
2360 }
2361
2362 done:
2363 return error;
2364 }
2365
2366 static int merge_annotated_commits(
2367 git_index **index_out,
2368 git_annotated_commit **base_out,
2369 git_repository *repo,
2370 git_annotated_commit *ours,
2371 git_annotated_commit *theirs,
2372 size_t recursion_level,
2373 const git_merge_options *opts)
2374 {
2375 git_annotated_commit *base = NULL;
2376 git_iterator *base_iter = NULL, *our_iter = NULL, *their_iter = NULL;
2377 int error;
2378
2379 if ((error = compute_base(&base, repo, ours, theirs, opts,
2380 recursion_level)) < 0) {
2381
2382 if (error != GIT_ENOTFOUND)
2383 goto done;
2384
2385 git_error_clear();
2386 }
2387
2388 if ((error = iterator_for_annotated_commit(&base_iter, base)) < 0 ||
2389 (error = iterator_for_annotated_commit(&our_iter, ours)) < 0 ||
2390 (error = iterator_for_annotated_commit(&their_iter, theirs)) < 0 ||
2391 (error = git_merge__iterators(index_out, repo, base_iter, our_iter,
2392 their_iter, opts)) < 0)
2393 goto done;
2394
2395 if (base_out) {
2396 *base_out = base;
2397 base = NULL;
2398 }
2399
2400 done:
2401 git_annotated_commit_free(base);
2402 git_iterator_free(base_iter);
2403 git_iterator_free(our_iter);
2404 git_iterator_free(their_iter);
2405 return error;
2406 }
2407
2408
2409 int git_merge_commits(
2410 git_index **out,
2411 git_repository *repo,
2412 const git_commit *our_commit,
2413 const git_commit *their_commit,
2414 const git_merge_options *opts)
2415 {
2416 git_annotated_commit *ours = NULL, *theirs = NULL, *base = NULL;
2417 int error = 0;
2418
2419 if ((error = git_annotated_commit_from_commit(&ours, (git_commit *)our_commit)) < 0 ||
2420 (error = git_annotated_commit_from_commit(&theirs, (git_commit *)their_commit)) < 0)
2421 goto done;
2422
2423 error = merge_annotated_commits(out, &base, repo, ours, theirs, 0, opts);
2424
2425 done:
2426 git_annotated_commit_free(ours);
2427 git_annotated_commit_free(theirs);
2428 git_annotated_commit_free(base);
2429 return error;
2430 }
2431
2432 /* Merge setup / cleanup */
2433
2434 static int write_merge_head(
2435 git_repository *repo,
2436 const git_annotated_commit *heads[],
2437 size_t heads_len)
2438 {
2439 git_filebuf file = GIT_FILEBUF_INIT;
2440 git_buf file_path = GIT_BUF_INIT;
2441 size_t i;
2442 int error = 0;
2443
2444 assert(repo && heads);
2445
2446 if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 ||
2447 (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
2448 goto cleanup;
2449
2450 for (i = 0; i < heads_len; i++) {
2451 if ((error = git_filebuf_printf(&file, "%s\n", heads[i]->id_str)) < 0)
2452 goto cleanup;
2453 }
2454
2455 error = git_filebuf_commit(&file);
2456
2457 cleanup:
2458 if (error < 0)
2459 git_filebuf_cleanup(&file);
2460
2461 git_buf_dispose(&file_path);
2462
2463 return error;
2464 }
2465
2466 static int write_merge_mode(git_repository *repo)
2467 {
2468 git_filebuf file = GIT_FILEBUF_INIT;
2469 git_buf file_path = GIT_BUF_INIT;
2470 int error = 0;
2471
2472 assert(repo);
2473
2474 if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 ||
2475 (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
2476 goto cleanup;
2477
2478 if ((error = git_filebuf_write(&file, "no-ff", 5)) < 0)
2479 goto cleanup;
2480
2481 error = git_filebuf_commit(&file);
2482
2483 cleanup:
2484 if (error < 0)
2485 git_filebuf_cleanup(&file);
2486
2487 git_buf_dispose(&file_path);
2488
2489 return error;
2490 }
2491
2492 struct merge_msg_entry {
2493 const git_annotated_commit *merge_head;
2494 bool written;
2495 };
2496
2497 static int msg_entry_is_branch(
2498 const struct merge_msg_entry *entry,
2499 git_vector *entries)
2500 {
2501 GIT_UNUSED(entries);
2502
2503 return (entry->written == 0 &&
2504 entry->merge_head->remote_url == NULL &&
2505 entry->merge_head->ref_name != NULL &&
2506 git__strncmp(GIT_REFS_HEADS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_HEADS_DIR)) == 0);
2507 }
2508
2509 static int msg_entry_is_tracking(
2510 const struct merge_msg_entry *entry,
2511 git_vector *entries)
2512 {
2513 GIT_UNUSED(entries);
2514
2515 return (entry->written == 0 &&
2516 entry->merge_head->remote_url == NULL &&
2517 entry->merge_head->ref_name != NULL &&
2518 git__strncmp(GIT_REFS_REMOTES_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_REMOTES_DIR)) == 0);
2519 }
2520
2521 static int msg_entry_is_tag(
2522 const struct merge_msg_entry *entry,
2523 git_vector *entries)
2524 {
2525 GIT_UNUSED(entries);
2526
2527 return (entry->written == 0 &&
2528 entry->merge_head->remote_url == NULL &&
2529 entry->merge_head->ref_name != NULL &&
2530 git__strncmp(GIT_REFS_TAGS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_TAGS_DIR)) == 0);
2531 }
2532
2533 static int msg_entry_is_remote(
2534 const struct merge_msg_entry *entry,
2535 git_vector *entries)
2536 {
2537 if (entry->written == 0 &&
2538 entry->merge_head->remote_url != NULL &&
2539 entry->merge_head->ref_name != NULL &&
2540 git__strncmp(GIT_REFS_HEADS_DIR, entry->merge_head->ref_name, strlen(GIT_REFS_HEADS_DIR)) == 0)
2541 {
2542 struct merge_msg_entry *existing;
2543
2544 /* Match only branches from the same remote */
2545 if (entries->length == 0)
2546 return 1;
2547
2548 existing = git_vector_get(entries, 0);
2549
2550 return (git__strcmp(existing->merge_head->remote_url,
2551 entry->merge_head->remote_url) == 0);
2552 }
2553
2554 return 0;
2555 }
2556
2557 static int msg_entry_is_oid(
2558 const struct merge_msg_entry *merge_msg_entry)
2559 {
2560 return (merge_msg_entry->written == 0 &&
2561 merge_msg_entry->merge_head->ref_name == NULL &&
2562 merge_msg_entry->merge_head->remote_url == NULL);
2563 }
2564
2565 static int merge_msg_entry_written(
2566 const struct merge_msg_entry *merge_msg_entry)
2567 {
2568 return (merge_msg_entry->written == 1);
2569 }
2570
2571 static int merge_msg_entries(
2572 git_vector *v,
2573 const struct merge_msg_entry *entries,
2574 size_t len,
2575 int (*match)(const struct merge_msg_entry *entry, git_vector *entries))
2576 {
2577 size_t i;
2578 int matches, total = 0;
2579
2580 git_vector_clear(v);
2581
2582 for (i = 0; i < len; i++) {
2583 if ((matches = match(&entries[i], v)) < 0)
2584 return matches;
2585 else if (!matches)
2586 continue;
2587
2588 git_vector_insert(v, (struct merge_msg_entry *)&entries[i]);
2589 total++;
2590 }
2591
2592 return total;
2593 }
2594
2595 static int merge_msg_write_entries(
2596 git_filebuf *file,
2597 git_vector *entries,
2598 const char *item_name,
2599 const char *item_plural_name,
2600 size_t ref_name_skip,
2601 const char *source,
2602 char sep)
2603 {
2604 struct merge_msg_entry *entry;
2605 size_t i;
2606 int error = 0;
2607
2608 if (entries->length == 0)
2609 return 0;
2610
2611 if (sep && (error = git_filebuf_printf(file, "%c ", sep)) < 0)
2612 goto done;
2613
2614 if ((error = git_filebuf_printf(file, "%s ",
2615 (entries->length == 1) ? item_name : item_plural_name)) < 0)
2616 goto done;
2617
2618 git_vector_foreach(entries, i, entry) {
2619 if (i > 0 &&
2620 (error = git_filebuf_printf(file, "%s", (i == entries->length - 1) ? " and " : ", ")) < 0)
2621 goto done;
2622
2623 if ((error = git_filebuf_printf(file, "'%s'", entry->merge_head->ref_name + ref_name_skip)) < 0)
2624 goto done;
2625
2626 entry->written = 1;
2627 }
2628
2629 if (source)
2630 error = git_filebuf_printf(file, " of %s", source);
2631
2632 done:
2633 return error;
2634 }
2635
2636 static int merge_msg_write_branches(
2637 git_filebuf *file,
2638 git_vector *entries,
2639 char sep)
2640 {
2641 return merge_msg_write_entries(file, entries,
2642 "branch", "branches", strlen(GIT_REFS_HEADS_DIR), NULL, sep);
2643 }
2644
2645 static int merge_msg_write_tracking(
2646 git_filebuf *file,
2647 git_vector *entries,
2648 char sep)
2649 {
2650 return merge_msg_write_entries(file, entries,
2651 "remote-tracking branch", "remote-tracking branches", 0, NULL, sep);
2652 }
2653
2654 static int merge_msg_write_tags(
2655 git_filebuf *file,
2656 git_vector *entries,
2657 char sep)
2658 {
2659 return merge_msg_write_entries(file, entries,
2660 "tag", "tags", strlen(GIT_REFS_TAGS_DIR), NULL, sep);
2661 }
2662
2663 static int merge_msg_write_remotes(
2664 git_filebuf *file,
2665 git_vector *entries,
2666 char sep)
2667 {
2668 const char *source;
2669
2670 if (entries->length == 0)
2671 return 0;
2672
2673 source = ((struct merge_msg_entry *)entries->contents[0])->merge_head->remote_url;
2674
2675 return merge_msg_write_entries(file, entries,
2676 "branch", "branches", strlen(GIT_REFS_HEADS_DIR), source, sep);
2677 }
2678
2679 static int write_merge_msg(
2680 git_repository *repo,
2681 const git_annotated_commit *heads[],
2682 size_t heads_len)
2683 {
2684 git_filebuf file = GIT_FILEBUF_INIT;
2685 git_buf file_path = GIT_BUF_INIT;
2686 struct merge_msg_entry *entries;
2687 git_vector matching = GIT_VECTOR_INIT;
2688 size_t i;
2689 char sep = 0;
2690 int error = 0;
2691
2692 assert(repo && heads);
2693
2694 entries = git__calloc(heads_len, sizeof(struct merge_msg_entry));
2695 GIT_ERROR_CHECK_ALLOC(entries);
2696
2697 if (git_vector_init(&matching, heads_len, NULL) < 0) {
2698 git__free(entries);
2699 return -1;
2700 }
2701
2702 for (i = 0; i < heads_len; i++)
2703 entries[i].merge_head = heads[i];
2704
2705 if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
2706 (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0 ||
2707 (error = git_filebuf_write(&file, "Merge ", 6)) < 0)
2708 goto cleanup;
2709
2710 /*
2711 * This is to emulate the format of MERGE_MSG by core git.
2712 *
2713 * Core git will write all the commits specified by OID, in the order
2714 * provided, until the first named branch or tag is reached, at which
2715 * point all branches will be written in the order provided, then all
2716 * tags, then all remote tracking branches and finally all commits that
2717 * were specified by OID that were not already written.
2718 *
2719 * Yes. Really.
2720 */
2721 for (i = 0; i < heads_len; i++) {
2722 if (!msg_entry_is_oid(&entries[i]))
2723 break;
2724
2725 if ((error = git_filebuf_printf(&file,
2726 "%scommit '%s'", (i > 0) ? "; " : "",
2727 entries[i].merge_head->id_str)) < 0)
2728 goto cleanup;
2729
2730 entries[i].written = 1;
2731 }
2732
2733 if (i)
2734 sep = ';';
2735
2736 if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_branch)) < 0 ||
2737 (error = merge_msg_write_branches(&file, &matching, sep)) < 0)
2738 goto cleanup;
2739
2740 if (matching.length)
2741 sep =',';
2742
2743 if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_tracking)) < 0 ||
2744 (error = merge_msg_write_tracking(&file, &matching, sep)) < 0)
2745 goto cleanup;
2746
2747 if (matching.length)
2748 sep =',';
2749
2750 if ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_tag)) < 0 ||
2751 (error = merge_msg_write_tags(&file, &matching, sep)) < 0)
2752 goto cleanup;
2753
2754 if (matching.length)
2755 sep =',';
2756
2757 /* We should never be called with multiple remote branches, but handle
2758 * it in case we are... */
2759 while ((error = merge_msg_entries(&matching, entries, heads_len, msg_entry_is_remote)) > 0) {
2760 if ((error = merge_msg_write_remotes(&file, &matching, sep)) < 0)
2761 goto cleanup;
2762
2763 if (matching.length)
2764 sep =',';
2765 }
2766
2767 if (error < 0)
2768 goto cleanup;
2769
2770 for (i = 0; i < heads_len; i++) {
2771 if (merge_msg_entry_written(&entries[i]))
2772 continue;
2773
2774 if ((error = git_filebuf_printf(&file, "; commit '%s'",
2775 entries[i].merge_head->id_str)) < 0)
2776 goto cleanup;
2777 }
2778
2779 if ((error = git_filebuf_printf(&file, "\n")) < 0 ||
2780 (error = git_filebuf_commit(&file)) < 0)
2781 goto cleanup;
2782
2783 cleanup:
2784 if (error < 0)
2785 git_filebuf_cleanup(&file);
2786
2787 git_buf_dispose(&file_path);
2788
2789 git_vector_free(&matching);
2790 git__free(entries);
2791
2792 return error;
2793 }
2794
2795 int git_merge__setup(
2796 git_repository *repo,
2797 const git_annotated_commit *our_head,
2798 const git_annotated_commit *heads[],
2799 size_t heads_len)
2800 {
2801 int error = 0;
2802
2803 assert (repo && our_head && heads);
2804
2805 if ((error = git_repository__set_orig_head(repo, git_annotated_commit_id(our_head))) == 0 &&
2806 (error = write_merge_head(repo, heads, heads_len)) == 0 &&
2807 (error = write_merge_mode(repo)) == 0) {
2808 error = write_merge_msg(repo, heads, heads_len);
2809 }
2810
2811 return error;
2812 }
2813
2814 /* Merge branches */
2815
2816 static int merge_ancestor_head(
2817 git_annotated_commit **ancestor_head,
2818 git_repository *repo,
2819 const git_annotated_commit *our_head,
2820 const git_annotated_commit **their_heads,
2821 size_t their_heads_len)
2822 {
2823 git_oid *oids, ancestor_oid;
2824 size_t i, alloc_len;
2825 int error = 0;
2826
2827 assert(repo && our_head && their_heads);
2828
2829 GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, their_heads_len, 1);
2830 oids = git__calloc(alloc_len, sizeof(git_oid));
2831 GIT_ERROR_CHECK_ALLOC(oids);
2832
2833 git_oid_cpy(&oids[0], git_commit_id(our_head->commit));
2834
2835 for (i = 0; i < their_heads_len; i++)
2836 git_oid_cpy(&oids[i + 1], git_annotated_commit_id(their_heads[i]));
2837
2838 if ((error = git_merge_base_many(&ancestor_oid, repo, their_heads_len + 1, oids)) < 0)
2839 goto on_error;
2840
2841 error = git_annotated_commit_lookup(ancestor_head, repo, &ancestor_oid);
2842
2843 on_error:
2844 git__free(oids);
2845 return error;
2846 }
2847
2848 static const char *merge_their_label(const char *branchname)
2849 {
2850 const char *slash;
2851
2852 if ((slash = strrchr(branchname, '/')) == NULL)
2853 return branchname;
2854
2855 if (*(slash+1) == '\0')
2856 return "theirs";
2857
2858 return slash+1;
2859 }
2860
2861 static int merge_normalize_checkout_opts(
2862 git_checkout_options *out,
2863 git_repository *repo,
2864 const git_checkout_options *given_checkout_opts,
2865 unsigned int checkout_strategy,
2866 git_annotated_commit *ancestor,
2867 const git_annotated_commit *our_head,
2868 const git_annotated_commit **their_heads,
2869 size_t their_heads_len)
2870 {
2871 git_checkout_options default_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
2872 int error = 0;
2873
2874 GIT_UNUSED(repo);
2875
2876 if (given_checkout_opts != NULL)
2877 memcpy(out, given_checkout_opts, sizeof(git_checkout_options));
2878 else
2879 memcpy(out, &default_checkout_opts, sizeof(git_checkout_options));
2880
2881 out->checkout_strategy = checkout_strategy;
2882
2883 if (!out->ancestor_label) {
2884 if (ancestor && ancestor->type == GIT_ANNOTATED_COMMIT_REAL)
2885 out->ancestor_label = git_commit_summary(ancestor->commit);
2886 else if (ancestor)
2887 out->ancestor_label = "merged common ancestors";
2888 else
2889 out->ancestor_label = "empty base";
2890 }
2891
2892 if (!out->our_label) {
2893 if (our_head && our_head->ref_name)
2894 out->our_label = our_head->ref_name;
2895 else
2896 out->our_label = "ours";
2897 }
2898
2899 if (!out->their_label) {
2900 if (their_heads_len == 1 && their_heads[0]->ref_name)
2901 out->their_label = merge_their_label(their_heads[0]->ref_name);
2902 else if (their_heads_len == 1)
2903 out->their_label = their_heads[0]->id_str;
2904 else
2905 out->their_label = "theirs";
2906 }
2907
2908 return error;
2909 }
2910
2911 static int merge_check_index(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
2912 {
2913 git_tree *head_tree = NULL;
2914 git_index *index_repo = NULL;
2915 git_iterator *iter_repo = NULL, *iter_new = NULL;
2916 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
2917 git_diff *staged_diff_list = NULL, *index_diff_list = NULL;
2918 git_diff_delta *delta;
2919 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
2920 git_vector staged_paths = GIT_VECTOR_INIT;
2921 size_t i;
2922 int error = 0;
2923
2924 GIT_UNUSED(merged_paths);
2925
2926 *conflicts = 0;
2927
2928 /* No staged changes may exist unless the change staged is identical to
2929 * the result of the merge. This allows one to apply to merge manually,
2930 * then run merge. Any other staged change would be overwritten by
2931 * a reset merge.
2932 */
2933 if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
2934 (error = git_repository_index(&index_repo, repo)) < 0 ||
2935 (error = git_diff_tree_to_index(&staged_diff_list, repo, head_tree, index_repo, &opts)) < 0)
2936 goto done;
2937
2938 if (staged_diff_list->deltas.length == 0)
2939 goto done;
2940
2941 git_vector_foreach(&staged_diff_list->deltas, i, delta) {
2942 if ((error = git_vector_insert(&staged_paths, (char *)delta->new_file.path)) < 0)
2943 goto done;
2944 }
2945
2946 iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
2947 iter_opts.pathlist.strings = (char **)staged_paths.contents;
2948 iter_opts.pathlist.count = staged_paths.length;
2949
2950 if ((error = git_iterator_for_index(&iter_repo, repo, index_repo, &iter_opts)) < 0 ||
2951 (error = git_iterator_for_index(&iter_new, repo, index_new, &iter_opts)) < 0 ||
2952 (error = git_diff__from_iterators(&index_diff_list, repo, iter_repo, iter_new, &opts)) < 0)
2953 goto done;
2954
2955 *conflicts = index_diff_list->deltas.length;
2956
2957 done:
2958 git_tree_free(head_tree);
2959 git_index_free(index_repo);
2960 git_iterator_free(iter_repo);
2961 git_iterator_free(iter_new);
2962 git_diff_free(staged_diff_list);
2963 git_diff_free(index_diff_list);
2964 git_vector_free(&staged_paths);
2965
2966 return error;
2967 }
2968
2969 static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
2970 {
2971 git_diff *wd_diff_list = NULL;
2972 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
2973 int error = 0;
2974
2975 GIT_UNUSED(index_new);
2976
2977 *conflicts = 0;
2978
2979 /* We need to have merged at least 1 file for the possibility to exist to
2980 * have conflicts with the workdir. Passing 0 as the pathspec count paramter
2981 * will consider all files in the working directory, that is, we may detect
2982 * a conflict if there were untracked files in the workdir prior to starting
2983 * the merge. This typically happens when cherry-picking a commmit whose
2984 * changes have already been applied.
2985 */
2986 if (merged_paths->length == 0)
2987 return 0;
2988
2989 opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
2990
2991 /* Workdir changes may exist iff they do not conflict with changes that
2992 * will be applied by the merge (including conflicts). Ensure that there
2993 * are no changes in the workdir to these paths.
2994 */
2995 opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
2996 opts.pathspec.count = merged_paths->length;
2997 opts.pathspec.strings = (char **)merged_paths->contents;
2998 opts.ignore_submodules = GIT_SUBMODULE_IGNORE_ALL;
2999
3000 if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, NULL, &opts)) < 0)
3001 goto done;
3002
3003 *conflicts = wd_diff_list->deltas.length;
3004
3005 done:
3006 git_diff_free(wd_diff_list);
3007
3008 return error;
3009 }
3010
3011 int git_merge__check_result(git_repository *repo, git_index *index_new)
3012 {
3013 git_tree *head_tree = NULL;
3014 git_iterator *iter_head = NULL, *iter_new = NULL;
3015 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
3016 git_diff *merged_list = NULL;
3017 git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
3018 git_diff_delta *delta;
3019 git_vector paths = GIT_VECTOR_INIT;
3020 size_t i, index_conflicts = 0, wd_conflicts = 0, conflicts;
3021 const git_index_entry *e;
3022 int error = 0;
3023
3024 iter_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
3025
3026 if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
3027 (error = git_iterator_for_tree(&iter_head, head_tree, &iter_opts)) < 0 ||
3028 (error = git_iterator_for_index(&iter_new, repo, index_new, &iter_opts)) < 0 ||
3029 (error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
3030 goto done;
3031
3032 git_vector_foreach(&merged_list->deltas, i, delta) {
3033 if ((error = git_vector_insert(&paths, (char *)delta->new_file.path)) < 0)
3034 goto done;
3035 }
3036
3037 for (i = 0; i < git_index_entrycount(index_new); i++) {
3038 e = git_index_get_byindex(index_new, i);
3039
3040 if (git_index_entry_is_conflict(e) &&
3041 (git_vector_last(&paths) == NULL ||
3042 strcmp(git_vector_last(&paths), e->path) != 0)) {
3043
3044 if ((error = git_vector_insert(&paths, (char *)e->path)) < 0)
3045 goto done;
3046 }
3047 }
3048
3049 /* Make sure the index and workdir state do not prevent merging */
3050 if ((error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
3051 (error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
3052 goto done;
3053
3054 if ((conflicts = index_conflicts + wd_conflicts) > 0) {
3055 git_error_set(GIT_ERROR_MERGE, "%" PRIuZ " uncommitted change%s would be overwritten by merge",
3056 conflicts, (conflicts != 1) ? "s" : "");
3057 error = GIT_ECONFLICT;
3058 }
3059
3060 done:
3061 git_vector_free(&paths);
3062 git_tree_free(head_tree);
3063 git_iterator_free(iter_head);
3064 git_iterator_free(iter_new);
3065 git_diff_free(merged_list);
3066
3067 return error;
3068 }
3069
3070 int git_merge__append_conflicts_to_merge_msg(
3071 git_repository *repo,
3072 git_index *index)
3073 {
3074 git_filebuf file = GIT_FILEBUF_INIT;
3075 git_buf file_path = GIT_BUF_INIT;
3076 const char *last = NULL;
3077 size_t i;
3078 int error;
3079
3080 if (!git_index_has_conflicts(index))
3081 return 0;
3082
3083 if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
3084 (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0)
3085 goto cleanup;
3086
3087 git_filebuf_printf(&file, "\nConflicts:\n");
3088
3089 for (i = 0; i < git_index_entrycount(index); i++) {
3090 const git_index_entry *e = git_index_get_byindex(index, i);
3091
3092 if (!git_index_entry_is_conflict(e))
3093 continue;
3094
3095 if (last == NULL || strcmp(e->path, last) != 0)
3096 git_filebuf_printf(&file, "\t%s\n", e->path);
3097
3098 last = e->path;
3099 }
3100
3101 error = git_filebuf_commit(&file);
3102
3103 cleanup:
3104 if (error < 0)
3105 git_filebuf_cleanup(&file);
3106
3107 git_buf_dispose(&file_path);
3108
3109 return error;
3110 }
3111
3112 static int merge_state_cleanup(git_repository *repo)
3113 {
3114 const char *state_files[] = {
3115 GIT_MERGE_HEAD_FILE,
3116 GIT_MERGE_MODE_FILE,
3117 GIT_MERGE_MSG_FILE,
3118 };
3119
3120 return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
3121 }
3122
3123 static int merge_heads(
3124 git_annotated_commit **ancestor_head_out,
3125 git_annotated_commit **our_head_out,
3126 git_repository *repo,
3127 git_reference *our_ref,
3128 const git_annotated_commit **their_heads,
3129 size_t their_heads_len)
3130 {
3131 git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
3132 int error = 0;
3133
3134 *ancestor_head_out = NULL;
3135 *our_head_out = NULL;
3136
3137 if ((error = git_annotated_commit_from_ref(&our_head, repo, our_ref)) < 0)
3138 goto done;
3139
3140 if ((error = merge_ancestor_head(&ancestor_head, repo, our_head, their_heads, their_heads_len)) < 0) {
3141 if (error != GIT_ENOTFOUND)
3142 goto done;
3143
3144 git_error_clear();
3145 error = 0;
3146 }
3147
3148 *ancestor_head_out = ancestor_head;
3149 *our_head_out = our_head;
3150
3151 done:
3152 if (error < 0) {
3153 git_annotated_commit_free(ancestor_head);
3154 git_annotated_commit_free(our_head);
3155 }
3156
3157 return error;
3158 }
3159
3160 static int merge_preference(git_merge_preference_t *out, git_repository *repo)
3161 {
3162 git_config *config;
3163 const char *value;
3164 int bool_value, error = 0;
3165
3166 *out = GIT_MERGE_PREFERENCE_NONE;
3167
3168 if ((error = git_repository_config_snapshot(&config, repo)) < 0)
3169 goto done;
3170
3171 if ((error = git_config_get_string(&value, config, "merge.ff")) < 0) {
3172 if (error == GIT_ENOTFOUND) {
3173 git_error_clear();
3174 error = 0;
3175 }
3176
3177 goto done;
3178 }
3179
3180 if (git_config_parse_bool(&bool_value, value) == 0) {
3181 if (!bool_value)
3182 *out |= GIT_MERGE_PREFERENCE_NO_FASTFORWARD;
3183 } else {
3184 if (strcasecmp(value, "only") == 0)
3185 *out |= GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY;
3186 }
3187
3188 done:
3189 git_config_free(config);
3190 return error;
3191 }
3192
3193 int git_merge_analysis_for_ref(
3194 git_merge_analysis_t *analysis_out,
3195 git_merge_preference_t *preference_out,
3196 git_repository *repo,
3197 git_reference *our_ref,
3198 const git_annotated_commit **their_heads,
3199 size_t their_heads_len)
3200 {
3201 git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
3202 int error = 0;
3203 bool unborn;
3204
3205 assert(analysis_out && preference_out && repo && their_heads && their_heads_len > 0);
3206
3207 if (their_heads_len != 1) {
3208 git_error_set(GIT_ERROR_MERGE, "can only merge a single branch");
3209 error = -1;
3210 goto done;
3211 }
3212
3213 *analysis_out = GIT_MERGE_ANALYSIS_NONE;
3214
3215 if ((error = merge_preference(preference_out, repo)) < 0)
3216 goto done;
3217
3218 if ((error = git_reference__is_unborn_head(&unborn, our_ref, repo)) < 0)
3219 goto done;
3220
3221 if (unborn) {
3222 *analysis_out |= GIT_MERGE_ANALYSIS_FASTFORWARD | GIT_MERGE_ANALYSIS_UNBORN;
3223 error = 0;
3224 goto done;
3225 }
3226
3227 if ((error = merge_heads(&ancestor_head, &our_head, repo, our_ref, their_heads, their_heads_len)) < 0)
3228 goto done;
3229
3230 /* We're up-to-date if we're trying to merge our own common ancestor. */
3231 if (ancestor_head && git_oid_equal(
3232 git_annotated_commit_id(ancestor_head), git_annotated_commit_id(their_heads[0])))
3233 *analysis_out |= GIT_MERGE_ANALYSIS_UP_TO_DATE;
3234
3235 /* We're fastforwardable if we're our own common ancestor. */
3236 else if (ancestor_head && git_oid_equal(
3237 git_annotated_commit_id(ancestor_head), git_annotated_commit_id(our_head)))
3238 *analysis_out |= GIT_MERGE_ANALYSIS_FASTFORWARD | GIT_MERGE_ANALYSIS_NORMAL;
3239
3240 /* Otherwise, just a normal merge is possible. */
3241 else
3242 *analysis_out |= GIT_MERGE_ANALYSIS_NORMAL;
3243
3244 done:
3245 git_annotated_commit_free(ancestor_head);
3246 git_annotated_commit_free(our_head);
3247 return error;
3248 }
3249
3250 int git_merge_analysis(
3251 git_merge_analysis_t *analysis_out,
3252 git_merge_preference_t *preference_out,
3253 git_repository *repo,
3254 const git_annotated_commit **their_heads,
3255 size_t their_heads_len)
3256 {
3257 git_reference *head_ref = NULL;
3258 int error = 0;
3259
3260 if ((error = git_reference_lookup(&head_ref, repo, GIT_HEAD_FILE)) < 0) {
3261 git_error_set(GIT_ERROR_MERGE, "failed to lookup HEAD reference");
3262 return error;
3263 }
3264
3265 error = git_merge_analysis_for_ref(analysis_out, preference_out, repo, head_ref, their_heads, their_heads_len);
3266
3267 git_reference_free(head_ref);
3268
3269 return error;
3270 }
3271
3272 int git_merge(
3273 git_repository *repo,
3274 const git_annotated_commit **their_heads,
3275 size_t their_heads_len,
3276 const git_merge_options *merge_opts,
3277 const git_checkout_options *given_checkout_opts)
3278 {
3279 git_reference *our_ref = NULL;
3280 git_checkout_options checkout_opts;
3281 git_annotated_commit *our_head = NULL, *base = NULL;
3282 git_index *repo_index = NULL, *index = NULL;
3283 git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
3284 unsigned int checkout_strategy;
3285 int error = 0;
3286
3287 assert(repo && their_heads && their_heads_len > 0);
3288
3289 if (their_heads_len != 1) {
3290 git_error_set(GIT_ERROR_MERGE, "can only merge a single branch");
3291 return -1;
3292 }
3293
3294 if ((error = git_repository__ensure_not_bare(repo, "merge")) < 0)
3295 goto done;
3296
3297 checkout_strategy = given_checkout_opts ?
3298 given_checkout_opts->checkout_strategy :
3299 GIT_CHECKOUT_SAFE;
3300
3301 if ((error = git_indexwriter_init_for_operation(&indexwriter, repo,
3302 &checkout_strategy)) < 0)
3303 goto done;
3304
3305 if ((error = git_repository_index(&repo_index, repo) < 0) ||
3306 (error = git_index_read(repo_index, 0) < 0))
3307 goto done;
3308
3309 /* Write the merge setup files to the repository. */
3310 if ((error = git_annotated_commit_from_head(&our_head, repo)) < 0 ||
3311 (error = git_merge__setup(repo, our_head, their_heads,
3312 their_heads_len)) < 0)
3313 goto done;
3314
3315 /* TODO: octopus */
3316
3317 if ((error = merge_annotated_commits(&index, &base, repo, our_head,
3318 (git_annotated_commit *)their_heads[0], 0, merge_opts)) < 0 ||
3319 (error = git_merge__check_result(repo, index)) < 0 ||
3320 (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0)
3321 goto done;
3322
3323 /* check out the merge results */
3324
3325 if ((error = merge_normalize_checkout_opts(&checkout_opts, repo,
3326 given_checkout_opts, checkout_strategy,
3327 base, our_head, their_heads, their_heads_len)) < 0 ||
3328 (error = git_checkout_index(repo, index, &checkout_opts)) < 0)
3329 goto done;
3330
3331 error = git_indexwriter_commit(&indexwriter);
3332
3333 done:
3334 if (error < 0)
3335 merge_state_cleanup(repo);
3336
3337 git_indexwriter_cleanup(&indexwriter);
3338 git_index_free(index);
3339 git_annotated_commit_free(our_head);
3340 git_annotated_commit_free(base);
3341 git_reference_free(our_ref);
3342 git_index_free(repo_index);
3343
3344 return error;
3345 }
3346
3347 int git_merge_options_init(git_merge_options *opts, unsigned int version)
3348 {
3349 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
3350 opts, version, git_merge_options, GIT_MERGE_OPTIONS_INIT);
3351 return 0;
3352 }
3353
3354 #ifndef GIT_DEPRECATE_HARD
3355 int git_merge_init_options(git_merge_options *opts, unsigned int version)
3356 {
3357 return git_merge_options_init(opts, version);
3358 }
3359 #endif
3360
3361 int git_merge_file_input_init(git_merge_file_input *input, unsigned int version)
3362 {
3363 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
3364 input, version, git_merge_file_input, GIT_MERGE_FILE_INPUT_INIT);
3365 return 0;
3366 }
3367
3368 #ifndef GIT_DEPRECATE_HARD
3369 int git_merge_file_init_input(git_merge_file_input *input, unsigned int version)
3370 {
3371 return git_merge_file_input_init(input, version);
3372 }
3373 #endif
3374
3375 int git_merge_file_options_init(
3376 git_merge_file_options *opts, unsigned int version)
3377 {
3378 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
3379 opts, version, git_merge_file_options, GIT_MERGE_FILE_OPTIONS_INIT);
3380 return 0;
3381 }
3382
3383 #ifndef GIT_DEPRECATE_HARD
3384 int git_merge_file_init_options(
3385 git_merge_file_options *opts, unsigned int version)
3386 {
3387 return git_merge_file_options_init(opts, version);
3388 }
3389 #endif