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