Skip to content

Commit da1f515

Browse files
committed
merge_bases_many(): split out the logic to paint history
Introduce a new helper function paint_down_to_common() that takes the same parameters as merge_bases_many(), but without the first optimization of not painting anything when "one" is one of the "twos" (or vice versa), and the last clean-up of removing the common ancestor that is known to be an ancestor of another common one. This way, the caller of the new function could tell if "one" is reachable from any of the "twos" by simply looking at the flag bits of "one". If (and only if) it is painted in PARENT2, it is reachable from one of the "twos". Signed-off-by: Junio C Hamano <[email protected]>
1 parent b0f9e9e commit da1f515

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

commit.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -581,28 +581,12 @@ static struct commit *interesting(struct commit_list *list)
581581
return NULL;
582582
}
583583

584-
static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
584+
static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
585585
{
586586
struct commit_list *list = NULL;
587587
struct commit_list *result = NULL;
588588
int i;
589589

590-
for (i = 0; i < n; i++) {
591-
if (one == twos[i])
592-
/*
593-
* We do not mark this even with RESULT so we do not
594-
* have to clean it up.
595-
*/
596-
return commit_list_insert(one, &result);
597-
}
598-
599-
if (parse_commit(one))
600-
return NULL;
601-
for (i = 0; i < n; i++) {
602-
if (parse_commit(twos[i]))
603-
return NULL;
604-
}
605-
606590
one->object.flags |= PARENT1;
607591
commit_list_insert_by_date(one, &list);
608592
for (i = 0; i < n; i++) {
@@ -643,9 +627,34 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
643627
}
644628
}
645629

646-
/* Clean up the result to remove stale ones */
647630
free_commit_list(list);
648-
list = result; result = NULL;
631+
return result;
632+
}
633+
634+
static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
635+
{
636+
struct commit_list *list = NULL;
637+
struct commit_list *result = NULL;
638+
int i;
639+
640+
for (i = 0; i < n; i++) {
641+
if (one == twos[i])
642+
/*
643+
* We do not mark this even with RESULT so we do not
644+
* have to clean it up.
645+
*/
646+
return commit_list_insert(one, &result);
647+
}
648+
649+
if (parse_commit(one))
650+
return NULL;
651+
for (i = 0; i < n; i++) {
652+
if (parse_commit(twos[i]))
653+
return NULL;
654+
}
655+
656+
list = paint_down_to_common(one, n, twos);
657+
649658
while (list) {
650659
struct commit_list *next = list->next;
651660
if (!(list->item->object.flags & STALE))

0 commit comments

Comments
 (0)