File Coverage

deps/libgit2/src/libgit2/merge.c
Criterion Covered Total %
statement 1037 1666 62.2
branch 581 1320 44.0
condition n/a
subroutine n/a
pod n/a
total 1618 2986 54.1


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