1 #include "git-compat-util.h"
4 #include "commit-graph.h"
7 #include "prio-queue.h"
9 #include "ref-filter.h"
12 #include "commit-reach.h"
14 /* Remember to update object flag allocation in object.h */
15 #define PARENT1 (1u<<16)
16 #define PARENT2 (1u<<17)
17 #define STALE (1u<<18)
18 #define RESULT (1u<<19)
20 static const unsigned all_flags
= (PARENT1
| PARENT2
| STALE
| RESULT
);
22 static int compare_commits_by_gen(const void *_a
, const void *_b
)
24 const struct commit
*a
= *(const struct commit
* const *)_a
;
25 const struct commit
*b
= *(const struct commit
* const *)_b
;
27 timestamp_t generation_a
= commit_graph_generation(a
);
28 timestamp_t generation_b
= commit_graph_generation(b
);
30 if (generation_a
< generation_b
)
32 if (generation_a
> generation_b
)
34 if (a
->date
< b
->date
)
36 if (a
->date
> b
->date
)
41 static int queue_has_nonstale(struct prio_queue
*queue
)
44 for (i
= 0; i
< queue
->nr
; i
++) {
45 struct commit
*commit
= queue
->array
[i
].data
;
46 if (!(commit
->object
.flags
& STALE
))
52 /* all input commits in one and twos[] must have been parsed! */
53 static struct commit_list
*paint_down_to_common(struct repository
*r
,
54 struct commit
*one
, int n
,
56 timestamp_t min_generation
)
58 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
59 struct commit_list
*result
= NULL
;
61 timestamp_t last_gen
= GENERATION_NUMBER_INFINITY
;
63 if (!min_generation
&& !corrected_commit_dates_enabled(r
))
64 queue
.compare
= compare_commits_by_commit_date
;
66 one
->object
.flags
|= PARENT1
;
68 commit_list_append(one
, &result
);
71 prio_queue_put(&queue
, one
);
73 for (i
= 0; i
< n
; i
++) {
74 twos
[i
]->object
.flags
|= PARENT2
;
75 prio_queue_put(&queue
, twos
[i
]);
78 while (queue_has_nonstale(&queue
)) {
79 struct commit
*commit
= prio_queue_get(&queue
);
80 struct commit_list
*parents
;
82 timestamp_t generation
= commit_graph_generation(commit
);
84 if (min_generation
&& generation
> last_gen
)
85 BUG("bad generation skip %"PRItime
" > %"PRItime
" at %s",
87 oid_to_hex(&commit
->object
.oid
));
88 last_gen
= generation
;
90 if (generation
< min_generation
)
93 flags
= commit
->object
.flags
& (PARENT1
| PARENT2
| STALE
);
94 if (flags
== (PARENT1
| PARENT2
)) {
95 if (!(commit
->object
.flags
& RESULT
)) {
96 commit
->object
.flags
|= RESULT
;
97 commit_list_insert_by_date(commit
, &result
);
99 /* Mark parents of a found merge stale */
102 parents
= commit
->parents
;
104 struct commit
*p
= parents
->item
;
105 parents
= parents
->next
;
106 if ((p
->object
.flags
& flags
) == flags
)
108 if (repo_parse_commit(r
, p
))
110 p
->object
.flags
|= flags
;
111 prio_queue_put(&queue
, p
);
115 clear_prio_queue(&queue
);
119 static struct commit_list
*merge_bases_many(struct repository
*r
,
120 struct commit
*one
, int n
,
121 struct commit
**twos
)
123 struct commit_list
*list
= NULL
;
124 struct commit_list
*result
= NULL
;
127 for (i
= 0; i
< n
; i
++) {
130 * We do not mark this even with RESULT so we do not
131 * have to clean it up.
133 return commit_list_insert(one
, &result
);
136 if (repo_parse_commit(r
, one
))
138 for (i
= 0; i
< n
; i
++) {
139 if (repo_parse_commit(r
, twos
[i
]))
143 list
= paint_down_to_common(r
, one
, n
, twos
, 0);
146 struct commit
*commit
= pop_commit(&list
);
147 if (!(commit
->object
.flags
& STALE
))
148 commit_list_insert_by_date(commit
, &result
);
153 struct commit_list
*get_octopus_merge_bases(struct commit_list
*in
)
155 struct commit_list
*i
, *j
, *k
, *ret
= NULL
;
160 commit_list_insert(in
->item
, &ret
);
162 for (i
= in
->next
; i
; i
= i
->next
) {
163 struct commit_list
*new_commits
= NULL
, *end
= NULL
;
165 for (j
= ret
; j
; j
= j
->next
) {
166 struct commit_list
*bases
;
167 bases
= get_merge_bases(i
->item
, j
->item
);
172 for (k
= bases
; k
; k
= k
->next
)
180 static int remove_redundant_no_gen(struct repository
*r
,
181 struct commit
**array
, int cnt
)
183 struct commit
**work
;
184 unsigned char *redundant
;
188 CALLOC_ARRAY(work
, cnt
);
189 redundant
= xcalloc(cnt
, 1);
190 ALLOC_ARRAY(filled_index
, cnt
- 1);
192 for (i
= 0; i
< cnt
; i
++)
193 repo_parse_commit(r
, array
[i
]);
194 for (i
= 0; i
< cnt
; i
++) {
195 struct commit_list
*common
;
196 timestamp_t min_generation
= commit_graph_generation(array
[i
]);
200 for (j
= filled
= 0; j
< cnt
; j
++) {
201 timestamp_t curr_generation
;
202 if (i
== j
|| redundant
[j
])
204 filled_index
[filled
] = j
;
205 work
[filled
++] = array
[j
];
207 curr_generation
= commit_graph_generation(array
[j
]);
208 if (curr_generation
< min_generation
)
209 min_generation
= curr_generation
;
211 common
= paint_down_to_common(r
, array
[i
], filled
,
212 work
, min_generation
);
213 if (array
[i
]->object
.flags
& PARENT2
)
215 for (j
= 0; j
< filled
; j
++)
216 if (work
[j
]->object
.flags
& PARENT1
)
217 redundant
[filled_index
[j
]] = 1;
218 clear_commit_marks(array
[i
], all_flags
);
219 clear_commit_marks_many(filled
, work
, all_flags
);
220 free_commit_list(common
);
223 /* Now collect the result */
224 COPY_ARRAY(work
, array
, cnt
);
225 for (i
= filled
= 0; i
< cnt
; i
++)
227 array
[filled
++] = work
[i
];
234 static int remove_redundant_with_gen(struct repository
*r
,
235 struct commit
**array
, int cnt
)
237 int i
, count_non_stale
= 0, count_still_independent
= cnt
;
238 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
239 struct commit
**walk_start
, **sorted
;
240 size_t walk_start_nr
= 0, walk_start_alloc
= cnt
;
244 * Sort the input by generation number, ascending. This allows
245 * us to increase the "min_generation" limit when we discover
246 * the commit with lowest generation is STALE. The index
247 * min_gen_pos points to the current position within 'array'
248 * that is not yet known to be STALE.
250 DUP_ARRAY(sorted
, array
, cnt
);
251 QSORT(sorted
, cnt
, compare_commits_by_gen
);
252 min_generation
= commit_graph_generation(sorted
[0]);
254 ALLOC_ARRAY(walk_start
, walk_start_alloc
);
256 /* Mark all parents of the input as STALE */
257 for (i
= 0; i
< cnt
; i
++) {
258 struct commit_list
*parents
;
260 repo_parse_commit(r
, array
[i
]);
261 array
[i
]->object
.flags
|= RESULT
;
262 parents
= array
[i
]->parents
;
265 repo_parse_commit(r
, parents
->item
);
266 if (!(parents
->item
->object
.flags
& STALE
)) {
267 parents
->item
->object
.flags
|= STALE
;
268 ALLOC_GROW(walk_start
, walk_start_nr
+ 1, walk_start_alloc
);
269 walk_start
[walk_start_nr
++] = parents
->item
;
271 parents
= parents
->next
;
275 QSORT(walk_start
, walk_start_nr
, compare_commits_by_gen
);
277 /* remove STALE bit for now to allow walking through parents */
278 for (i
= 0; i
< walk_start_nr
; i
++)
279 walk_start
[i
]->object
.flags
&= ~STALE
;
282 * Start walking from the highest generation. Hopefully, it will
283 * find all other items during the first-parent walk, and we can
284 * terminate early. Otherwise, we will do the same amount of work
287 for (i
= walk_start_nr
- 1; i
>= 0 && count_still_independent
> 1; i
--) {
288 /* push the STALE bits up to min generation */
289 struct commit_list
*stack
= NULL
;
291 commit_list_insert(walk_start
[i
], &stack
);
292 walk_start
[i
]->object
.flags
|= STALE
;
295 struct commit_list
*parents
;
296 struct commit
*c
= stack
->item
;
298 repo_parse_commit(r
, c
);
300 if (c
->object
.flags
& RESULT
) {
301 c
->object
.flags
&= ~RESULT
;
302 if (--count_still_independent
<= 1)
304 if (oideq(&c
->object
.oid
, &sorted
[min_gen_pos
]->object
.oid
)) {
305 while (min_gen_pos
< cnt
- 1 &&
306 (sorted
[min_gen_pos
]->object
.flags
& STALE
))
308 min_generation
= commit_graph_generation(sorted
[min_gen_pos
]);
312 if (commit_graph_generation(c
) < min_generation
) {
317 parents
= c
->parents
;
319 if (!(parents
->item
->object
.flags
& STALE
)) {
320 parents
->item
->object
.flags
|= STALE
;
321 commit_list_insert(parents
->item
, &stack
);
324 parents
= parents
->next
;
327 /* pop if all parents have been visited already */
331 free_commit_list(stack
);
336 for (i
= 0; i
< cnt
; i
++)
337 array
[i
]->object
.flags
&= ~RESULT
;
339 /* rearrange array */
340 for (i
= count_non_stale
= 0; i
< cnt
; i
++) {
341 if (!(array
[i
]->object
.flags
& STALE
))
342 array
[count_non_stale
++] = array
[i
];
346 clear_commit_marks_many(walk_start_nr
, walk_start
, STALE
);
349 return count_non_stale
;
352 static int remove_redundant(struct repository
*r
, struct commit
**array
, int cnt
)
355 * Some commit in the array may be an ancestor of
356 * another commit. Move the independent commits to the
357 * beginning of 'array' and return their number. Callers
358 * should not rely upon the contents of 'array' after
361 if (generation_numbers_enabled(r
)) {
365 * If we have a single commit with finite generation
366 * number, then the _with_gen algorithm is preferred.
368 for (i
= 0; i
< cnt
; i
++) {
369 if (commit_graph_generation(array
[i
]) < GENERATION_NUMBER_INFINITY
)
370 return remove_redundant_with_gen(r
, array
, cnt
);
374 return remove_redundant_no_gen(r
, array
, cnt
);
377 static struct commit_list
*get_merge_bases_many_0(struct repository
*r
,
380 struct commit
**twos
,
383 struct commit_list
*list
;
384 struct commit
**rslt
;
385 struct commit_list
*result
;
388 result
= merge_bases_many(r
, one
, n
, twos
);
389 for (i
= 0; i
< n
; i
++) {
393 if (!result
|| !result
->next
) {
395 clear_commit_marks(one
, all_flags
);
396 clear_commit_marks_many(n
, twos
, all_flags
);
401 /* There are more than one */
402 cnt
= commit_list_count(result
);
403 CALLOC_ARRAY(rslt
, cnt
);
404 for (list
= result
, i
= 0; list
; list
= list
->next
)
405 rslt
[i
++] = list
->item
;
406 free_commit_list(result
);
408 clear_commit_marks(one
, all_flags
);
409 clear_commit_marks_many(n
, twos
, all_flags
);
411 cnt
= remove_redundant(r
, rslt
, cnt
);
413 for (i
= 0; i
< cnt
; i
++)
414 commit_list_insert_by_date(rslt
[i
], &result
);
419 struct commit_list
*repo_get_merge_bases_many(struct repository
*r
,
422 struct commit
**twos
)
424 return get_merge_bases_many_0(r
, one
, n
, twos
, 1);
427 struct commit_list
*repo_get_merge_bases_many_dirty(struct repository
*r
,
430 struct commit
**twos
)
432 return get_merge_bases_many_0(r
, one
, n
, twos
, 0);
435 struct commit_list
*repo_get_merge_bases(struct repository
*r
,
439 return get_merge_bases_many_0(r
, one
, 1, &two
, 1);
443 * Is "commit" a descendant of one of the elements on the "with_commit" list?
445 int repo_is_descendant_of(struct repository
*r
,
446 struct commit
*commit
,
447 struct commit_list
*with_commit
)
452 if (generation_numbers_enabled(the_repository
)) {
453 struct commit_list
*from_list
= NULL
;
455 commit_list_insert(commit
, &from_list
);
456 result
= can_all_from_reach(from_list
, with_commit
, 0);
457 free_commit_list(from_list
);
460 while (with_commit
) {
461 struct commit
*other
;
463 other
= with_commit
->item
;
464 with_commit
= with_commit
->next
;
465 if (repo_in_merge_bases_many(r
, other
, 1, &commit
))
473 * Is "commit" an ancestor of one of the "references"?
475 int repo_in_merge_bases_many(struct repository
*r
, struct commit
*commit
,
476 int nr_reference
, struct commit
**reference
)
478 struct commit_list
*bases
;
480 timestamp_t generation
, max_generation
= GENERATION_NUMBER_ZERO
;
482 if (repo_parse_commit(r
, commit
))
484 for (i
= 0; i
< nr_reference
; i
++) {
485 if (repo_parse_commit(r
, reference
[i
]))
488 generation
= commit_graph_generation(reference
[i
]);
489 if (generation
> max_generation
)
490 max_generation
= generation
;
493 generation
= commit_graph_generation(commit
);
494 if (generation
> max_generation
)
497 bases
= paint_down_to_common(r
, commit
,
498 nr_reference
, reference
,
500 if (commit
->object
.flags
& PARENT2
)
502 clear_commit_marks(commit
, all_flags
);
503 clear_commit_marks_many(nr_reference
, reference
, all_flags
);
504 free_commit_list(bases
);
509 * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
511 int repo_in_merge_bases(struct repository
*r
,
512 struct commit
*commit
,
513 struct commit
*reference
)
516 struct commit_list
*list
= NULL
;
517 struct commit_list
**next
= &list
;
519 next
= commit_list_append(commit
, next
);
520 res
= repo_is_descendant_of(r
, reference
, list
);
521 free_commit_list(list
);
526 struct commit_list
*reduce_heads(struct commit_list
*heads
)
528 struct commit_list
*p
;
529 struct commit_list
*result
= NULL
, **tail
= &result
;
530 struct commit
**array
;
537 for (p
= heads
; p
; p
= p
->next
)
538 p
->item
->object
.flags
&= ~STALE
;
539 for (p
= heads
, num_head
= 0; p
; p
= p
->next
) {
540 if (p
->item
->object
.flags
& STALE
)
542 p
->item
->object
.flags
|= STALE
;
545 CALLOC_ARRAY(array
, num_head
);
546 for (p
= heads
, i
= 0; p
; p
= p
->next
) {
547 if (p
->item
->object
.flags
& STALE
) {
548 array
[i
++] = p
->item
;
549 p
->item
->object
.flags
&= ~STALE
;
552 num_head
= remove_redundant(the_repository
, array
, num_head
);
553 for (i
= 0; i
< num_head
; i
++)
554 tail
= &commit_list_insert(array
[i
], tail
)->next
;
559 void reduce_heads_replace(struct commit_list
**heads
)
561 struct commit_list
*result
= reduce_heads(*heads
);
562 free_commit_list(*heads
);
566 int ref_newer(const struct object_id
*new_oid
, const struct object_id
*old_oid
)
569 struct commit
*old_commit
, *new_commit
;
570 struct commit_list
*old_commit_list
= NULL
;
574 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
575 * old_commit. Otherwise we require --force.
577 o
= deref_tag(the_repository
, parse_object(the_repository
, old_oid
),
579 if (!o
|| o
->type
!= OBJ_COMMIT
)
581 old_commit
= (struct commit
*) o
;
583 o
= deref_tag(the_repository
, parse_object(the_repository
, new_oid
),
585 if (!o
|| o
->type
!= OBJ_COMMIT
)
587 new_commit
= (struct commit
*) o
;
589 if (parse_commit(new_commit
) < 0)
592 commit_list_insert(old_commit
, &old_commit_list
);
593 ret
= repo_is_descendant_of(the_repository
,
594 new_commit
, old_commit_list
);
595 free_commit_list(old_commit_list
);
600 * Mimicking the real stack, this stack lives on the heap, avoiding stack
603 * At each recursion step, the stack items points to the commits whose
604 * ancestors are to be inspected.
606 struct contains_stack
{
608 struct contains_stack_entry
{
609 struct commit
*commit
;
610 struct commit_list
*parents
;
614 static int in_commit_list(const struct commit_list
*want
, struct commit
*c
)
616 for (; want
; want
= want
->next
)
617 if (oideq(&want
->item
->object
.oid
, &c
->object
.oid
))
623 * Test whether the candidate is contained in the list.
624 * Do not recurse to find out, though, but return -1 if inconclusive.
626 static enum contains_result
contains_test(struct commit
*candidate
,
627 const struct commit_list
*want
,
628 struct contains_cache
*cache
,
631 enum contains_result
*cached
= contains_cache_at(cache
, candidate
);
633 /* If we already have the answer cached, return that. */
638 if (in_commit_list(want
, candidate
)) {
639 *cached
= CONTAINS_YES
;
643 /* Otherwise, we don't know; prepare to recurse */
644 parse_commit_or_die(candidate
);
646 if (commit_graph_generation(candidate
) < cutoff
)
649 return CONTAINS_UNKNOWN
;
652 static void push_to_contains_stack(struct commit
*candidate
, struct contains_stack
*contains_stack
)
654 ALLOC_GROW(contains_stack
->contains_stack
, contains_stack
->nr
+ 1, contains_stack
->alloc
);
655 contains_stack
->contains_stack
[contains_stack
->nr
].commit
= candidate
;
656 contains_stack
->contains_stack
[contains_stack
->nr
++].parents
= candidate
->parents
;
659 static enum contains_result
contains_tag_algo(struct commit
*candidate
,
660 const struct commit_list
*want
,
661 struct contains_cache
*cache
)
663 struct contains_stack contains_stack
= { 0, 0, NULL
};
664 enum contains_result result
;
665 timestamp_t cutoff
= GENERATION_NUMBER_INFINITY
;
666 const struct commit_list
*p
;
668 for (p
= want
; p
; p
= p
->next
) {
669 timestamp_t generation
;
670 struct commit
*c
= p
->item
;
671 load_commit_graph_info(the_repository
, c
);
672 generation
= commit_graph_generation(c
);
673 if (generation
< cutoff
)
677 result
= contains_test(candidate
, want
, cache
, cutoff
);
678 if (result
!= CONTAINS_UNKNOWN
)
681 push_to_contains_stack(candidate
, &contains_stack
);
682 while (contains_stack
.nr
) {
683 struct contains_stack_entry
*entry
= &contains_stack
.contains_stack
[contains_stack
.nr
- 1];
684 struct commit
*commit
= entry
->commit
;
685 struct commit_list
*parents
= entry
->parents
;
688 *contains_cache_at(cache
, commit
) = CONTAINS_NO
;
692 * If we just popped the stack, parents->item has been marked,
693 * therefore contains_test will return a meaningful yes/no.
695 else switch (contains_test(parents
->item
, want
, cache
, cutoff
)) {
697 *contains_cache_at(cache
, commit
) = CONTAINS_YES
;
701 entry
->parents
= parents
->next
;
703 case CONTAINS_UNKNOWN
:
704 push_to_contains_stack(parents
->item
, &contains_stack
);
708 free(contains_stack
.contains_stack
);
709 return contains_test(candidate
, want
, cache
, cutoff
);
712 int commit_contains(struct ref_filter
*filter
, struct commit
*commit
,
713 struct commit_list
*list
, struct contains_cache
*cache
)
715 if (filter
->with_commit_tag_algo
)
716 return contains_tag_algo(commit
, list
, cache
) == CONTAINS_YES
;
717 return repo_is_descendant_of(the_repository
, commit
, list
);
720 int can_all_from_reach_with_flag(struct object_array
*from
,
721 unsigned int with_flag
,
722 unsigned int assign_flag
,
723 time_t min_commit_date
,
724 timestamp_t min_generation
)
726 struct commit
**list
= NULL
;
731 ALLOC_ARRAY(list
, from
->nr
);
733 for (i
= 0; i
< from
->nr
; i
++) {
734 struct object
*from_one
= from
->objects
[i
].item
;
736 if (!from_one
|| from_one
->flags
& assign_flag
)
739 from_one
= deref_tag(the_repository
, from_one
,
741 if (!from_one
|| from_one
->type
!= OBJ_COMMIT
) {
743 * no way to tell if this is reachable by
744 * looking at the ancestry chain alone, so
745 * leave a note to ourselves not to worry about
746 * this object anymore.
748 from
->objects
[i
].item
->flags
|= assign_flag
;
752 list
[nr_commits
] = (struct commit
*)from_one
;
753 if (parse_commit(list
[nr_commits
]) ||
754 commit_graph_generation(list
[nr_commits
]) < min_generation
) {
762 QSORT(list
, nr_commits
, compare_commits_by_gen
);
764 for (i
= 0; i
< nr_commits
; i
++) {
765 /* DFS from list[i] */
766 struct commit_list
*stack
= NULL
;
768 list
[i
]->object
.flags
|= assign_flag
;
769 commit_list_insert(list
[i
], &stack
);
772 struct commit_list
*parent
;
774 if (stack
->item
->object
.flags
& (with_flag
| RESULT
)) {
777 stack
->item
->object
.flags
|= RESULT
;
781 for (parent
= stack
->item
->parents
; parent
; parent
= parent
->next
) {
782 if (parent
->item
->object
.flags
& (with_flag
| RESULT
))
783 stack
->item
->object
.flags
|= RESULT
;
785 if (!(parent
->item
->object
.flags
& assign_flag
)) {
786 parent
->item
->object
.flags
|= assign_flag
;
788 if (parse_commit(parent
->item
) ||
789 parent
->item
->date
< min_commit_date
||
790 commit_graph_generation(parent
->item
) < min_generation
)
793 commit_list_insert(parent
->item
, &stack
);
802 if (!(list
[i
]->object
.flags
& (with_flag
| RESULT
))) {
809 clear_commit_marks_many(nr_commits
, list
, RESULT
| assign_flag
);
812 for (i
= 0; i
< from
->nr
; i
++)
813 from
->objects
[i
].item
->flags
&= ~assign_flag
;
818 int can_all_from_reach(struct commit_list
*from
, struct commit_list
*to
,
819 int cutoff_by_min_date
)
821 struct object_array from_objs
= OBJECT_ARRAY_INIT
;
822 time_t min_commit_date
= cutoff_by_min_date
? from
->item
->date
: 0;
823 struct commit_list
*from_iter
= from
, *to_iter
= to
;
825 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
828 add_object_array(&from_iter
->item
->object
, NULL
, &from_objs
);
830 if (!parse_commit(from_iter
->item
)) {
831 timestamp_t generation
;
832 if (from_iter
->item
->date
< min_commit_date
)
833 min_commit_date
= from_iter
->item
->date
;
835 generation
= commit_graph_generation(from_iter
->item
);
836 if (generation
< min_generation
)
837 min_generation
= generation
;
840 from_iter
= from_iter
->next
;
844 if (!parse_commit(to_iter
->item
)) {
845 timestamp_t generation
;
846 if (to_iter
->item
->date
< min_commit_date
)
847 min_commit_date
= to_iter
->item
->date
;
849 generation
= commit_graph_generation(to_iter
->item
);
850 if (generation
< min_generation
)
851 min_generation
= generation
;
854 to_iter
->item
->object
.flags
|= PARENT2
;
856 to_iter
= to_iter
->next
;
859 result
= can_all_from_reach_with_flag(&from_objs
, PARENT2
, PARENT1
,
860 min_commit_date
, min_generation
);
863 clear_commit_marks(from
->item
, PARENT1
);
868 clear_commit_marks(to
->item
, PARENT2
);
872 object_array_clear(&from_objs
);
876 struct commit_list
*get_reachable_subset(struct commit
**from
, int nr_from
,
877 struct commit
**to
, int nr_to
,
878 unsigned int reachable_flag
)
880 struct commit
**item
;
881 struct commit
*current
;
882 struct commit_list
*found_commits
= NULL
;
883 struct commit
**to_last
= to
+ nr_to
;
884 struct commit
**from_last
= from
+ nr_from
;
885 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
888 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
890 for (item
= to
; item
< to_last
; item
++) {
891 timestamp_t generation
;
892 struct commit
*c
= *item
;
895 generation
= commit_graph_generation(c
);
896 if (generation
< min_generation
)
897 min_generation
= generation
;
899 if (!(c
->object
.flags
& PARENT1
)) {
900 c
->object
.flags
|= PARENT1
;
905 for (item
= from
; item
< from_last
; item
++) {
906 struct commit
*c
= *item
;
907 if (!(c
->object
.flags
& PARENT2
)) {
908 c
->object
.flags
|= PARENT2
;
911 prio_queue_put(&queue
, *item
);
915 while (num_to_find
&& (current
= prio_queue_get(&queue
)) != NULL
) {
916 struct commit_list
*parents
;
918 if (current
->object
.flags
& PARENT1
) {
919 current
->object
.flags
&= ~PARENT1
;
920 current
->object
.flags
|= reachable_flag
;
921 commit_list_insert(current
, &found_commits
);
925 for (parents
= current
->parents
; parents
; parents
= parents
->next
) {
926 struct commit
*p
= parents
->item
;
930 if (commit_graph_generation(p
) < min_generation
)
933 if (p
->object
.flags
& PARENT2
)
936 p
->object
.flags
|= PARENT2
;
937 prio_queue_put(&queue
, p
);
941 clear_commit_marks_many(nr_to
, to
, PARENT1
);
942 clear_commit_marks_many(nr_from
, from
, PARENT2
);
944 return found_commits
;