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 <gitster@pobox.com>
Junio C Hamano committed
Aug 30, 2012 at 14:39 UTC
da1f515641f4853a6b7c4710392796ed08efaa6f
1 file changed
+28
-19
commit.c
+28
-19
@@ -581,28 +581,12 @@ static struct commit *interesting(struct commit_list *list)
581
return NULL;
582
}
583
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)
585
{
586
struct commit_list *list = NULL;
587
struct commit_list *result = NULL;
588
int i;
589
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
-
590
one->object.flags |= PARENT1;
591
commit_list_insert_by_date(one, &list);
592
for (i = 0; i < n; i++) {
@@ -643,9 +627,34 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
627
}
628
}
629
646
- /* Clean up the result to remove stale ones */
630
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
+
658
while (list) {
659
struct commit_list *next = list->next;
660
if (!(list->item->object.flags & STALE))