@matheusbsbs / matheus-bagliano / commits / 6a938648e1
Fork 0

Introduce get_merge_bases_many()

This introduces a new function get_merge_bases_many() which is a natural extension of two commit merge base computation. It is given one commit (one) and a set of other commits (twos), and computes the merge base of one and a merge across other commits. This is mostly useful to figure out the common ancestor when iterating over heads during an octopus merge. When making an octopus between commits A, B, C and D, we first merge tree of A and B, and then try to merge C with it. If we were making pairwise merge, we would be recording the tree resulting from the merge between A and B as a commit, say M, and then the next round we will be computing the merge base between M and C. o---C...* / . o---B...M / . o---o---A But during an octopus merge, we actually do not create a commit M. In order to figure out that the common ancestor to use for this merge, instead of computing the merge base between C and M, we can call merge_bases_many() with one set to C and twos containing A and B. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jun 27, 2008 at 18:22 UTC 6a938648e1454842157b84408acbb6471ec6745f
1 file changed +38 -18
commit.c
+38 -18
@@ -533,26 +533,34 @@ static struct commit *interesting(struct commit_list *list)
533 return NULL;
534 }
535
536 -static struct commit_list *merge_bases(struct commit *one, struct commit *two)
536 +static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
537 {
538 struct commit_list *list = NULL;
539 struct commit_list *result = NULL;
540 + int i;
541
541 - if (one == two)
542 - /* We do not mark this even with RESULT so we do not
543 - * have to clean it up.
544 - */
545 - return commit_list_insert(one, &result);
542 + for (i = 0; i < n; i++) {
543 + if (one == twos[i])
544 + /*
545 + * We do not mark this even with RESULT so we do not
546 + * have to clean it up.
547 + */
548 + return commit_list_insert(one, &result);
549 + }
550
551 if (parse_commit(one))
552 return NULL;
549 - if (parse_commit(two))
550 - return NULL;
553 + for (i = 0; i < n; i++) {
554 + if (parse_commit(twos[i]))
555 + return NULL;
556 + }
557
558 one->object.flags |= PARENT1;
553 - two->object.flags |= PARENT2;
559 insert_by_date(one, &list);
555 - insert_by_date(two, &list);
560 + for (i = 0; i < n; i++) {
561 + twos[i]->object.flags |= PARENT2;
562 + insert_by_date(twos[i], &list);
563 + }
564
565 while (interesting(list)) {
566 struct commit *commit;
@@ -627,21 +635,26 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
635 return ret;
636 }
637
630 -struct commit_list *get_merge_bases(struct commit *one,
631 - struct commit *two, int cleanup)
638 +struct commit_list *get_merge_bases_many(struct commit *one,
639 + int n,
640 + struct commit **twos,
641 + int cleanup)
642 {
643 struct commit_list *list;
644 struct commit **rslt;
645 struct commit_list *result;
646 int cnt, i, j;
647
638 - result = merge_bases(one, two);
639 - if (one == two)
640 - return result;
648 + result = merge_bases_many(one, n, twos);
649 + for (i = 0; i < n; i++) {
650 + if (one == twos[i])
651 + return result;
652 + }
653 if (!result || !result->next) {
654 if (cleanup) {
655 clear_commit_marks(one, all_flags);
644 - clear_commit_marks(two, all_flags);
656 + for (i = 0; i < n; i++)
657 + clear_commit_marks(twos[i], all_flags);
658 }
659 return result;
660 }
@@ -659,12 +672,13 @@ struct commit_list *get_merge_bases(struct commit *one,
672 free_commit_list(result);
673
674 clear_commit_marks(one, all_flags);
662 - clear_commit_marks(two, all_flags);
675 + for (i = 0; i < n; i++)
676 + clear_commit_marks(twos[i], all_flags);
677 for (i = 0; i < cnt - 1; i++) {
678 for (j = i+1; j < cnt; j++) {
679 if (!rslt[i] || !rslt[j])
680 continue;
667 - result = merge_bases(rslt[i], rslt[j]);
681 + result = merge_bases_many(rslt[i], 1, &rslt[j]);
682 clear_commit_marks(rslt[i], all_flags);
683 clear_commit_marks(rslt[j], all_flags);
684 for (list = result; list; list = list->next) {
@@ -686,6 +700,12 @@ struct commit_list *get_merge_bases(struct commit *one,
700 return result;
701 }
702
703 +struct commit_list *get_merge_bases(struct commit *one, struct commit *two,
704 + int cleanup)
705 +{
706 + return get_merge_bases_many(one, 1, &two, cleanup);
707 +}
708 +
709 int in_merge_bases(struct commit *commit, struct commit **reference, int num)
710 {
711 struct commit_list *bases, *b;