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