1 #include "git-compat-util.h"
3 #include "commit-graph.h"
6 #include "prio-queue.h"
7 #include "ref-filter.h"
10 #include "commit-reach.h"
11 #include "ewah/ewok.h"
13 /* Remember to update object flag allocation in object.h */
14 #define PARENT1 (1u<<16)
15 #define PARENT2 (1u<<17)
16 #define STALE (1u<<18)
17 #define RESULT (1u<<19)
19 static const unsigned all_flags
= (PARENT1
| PARENT2
| STALE
| RESULT
);
21 static int compare_commits_by_gen(const void *_a
, const void *_b
)
23 const struct commit
*a
= *(const struct commit
* const *)_a
;
24 const struct commit
*b
= *(const struct commit
* const *)_b
;
26 timestamp_t generation_a
= commit_graph_generation(a
);
27 timestamp_t generation_b
= commit_graph_generation(b
);
29 if (generation_a
< generation_b
)
31 if (generation_a
> generation_b
)
33 if (a
->date
< b
->date
)
35 if (a
->date
> b
->date
)
40 static int queue_has_nonstale(struct prio_queue
*queue
)
43 for (i
= 0; i
< queue
->nr
; i
++) {
44 struct commit
*commit
= queue
->array
[i
].data
;
45 if (!(commit
->object
.flags
& STALE
))
51 /* all input commits in one and twos[] must have been parsed! */
52 static int paint_down_to_common(struct repository
*r
,
53 struct commit
*one
, int n
,
55 timestamp_t min_generation
,
56 int ignore_missing_commits
,
57 struct commit_list
**result
)
59 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
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
)) {
109 clear_prio_queue(&queue
);
110 free_commit_list(*result
);
113 * At this stage, we know that the commit is
114 * missing: `repo_parse_commit()` uses
115 * `OBJECT_INFO_DIE_IF_CORRUPT` and therefore
116 * corrupt commits would already have been
117 * dispatched with a `die()`.
119 if (ignore_missing_commits
)
121 return error(_("could not parse commit %s"),
122 oid_to_hex(&p
->object
.oid
));
124 p
->object
.flags
|= flags
;
125 prio_queue_put(&queue
, p
);
129 clear_prio_queue(&queue
);
133 static int merge_bases_many(struct repository
*r
,
134 struct commit
*one
, int n
,
135 struct commit
**twos
,
136 struct commit_list
**result
)
138 struct commit_list
*list
= NULL
;
141 for (i
= 0; i
< n
; i
++) {
142 if (one
== twos
[i
]) {
144 * We do not mark this even with RESULT so we do not
145 * have to clean it up.
147 *result
= commit_list_insert(one
, result
);
154 if (repo_parse_commit(r
, one
))
155 return error(_("could not parse commit %s"),
156 oid_to_hex(&one
->object
.oid
));
157 for (i
= 0; i
< n
; i
++) {
160 if (repo_parse_commit(r
, twos
[i
]))
161 return error(_("could not parse commit %s"),
162 oid_to_hex(&twos
[i
]->object
.oid
));
165 if (paint_down_to_common(r
, one
, n
, twos
, 0, 0, &list
)) {
166 free_commit_list(list
);
171 struct commit
*commit
= pop_commit(&list
);
172 if (!(commit
->object
.flags
& STALE
))
173 commit_list_insert_by_date(commit
, result
);
178 int get_octopus_merge_bases(struct commit_list
*in
, struct commit_list
**result
)
180 struct commit_list
*i
, *j
, *k
;
185 commit_list_insert(in
->item
, result
);
187 for (i
= in
->next
; i
; i
= i
->next
) {
188 struct commit_list
*new_commits
= NULL
, *end
= NULL
;
190 for (j
= *result
; j
; j
= j
->next
) {
191 struct commit_list
*bases
= NULL
;
192 if (repo_get_merge_bases(the_repository
, i
->item
,
193 j
->item
, &bases
) < 0) {
194 free_commit_list(bases
);
195 free_commit_list(*result
);
203 for (k
= bases
; k
; k
= k
->next
)
206 free_commit_list(*result
);
207 *result
= new_commits
;
212 static int remove_redundant_no_gen(struct repository
*r
,
213 struct commit
**array
, int cnt
)
215 struct commit
**work
;
216 unsigned char *redundant
;
220 CALLOC_ARRAY(work
, cnt
);
221 redundant
= xcalloc(cnt
, 1);
222 ALLOC_ARRAY(filled_index
, cnt
- 1);
224 for (i
= 0; i
< cnt
; i
++)
225 repo_parse_commit(r
, array
[i
]);
226 for (i
= 0; i
< cnt
; i
++) {
227 struct commit_list
*common
= NULL
;
228 timestamp_t min_generation
= commit_graph_generation(array
[i
]);
232 for (j
= filled
= 0; j
< cnt
; j
++) {
233 timestamp_t curr_generation
;
234 if (i
== j
|| redundant
[j
])
236 filled_index
[filled
] = j
;
237 work
[filled
++] = array
[j
];
239 curr_generation
= commit_graph_generation(array
[j
]);
240 if (curr_generation
< min_generation
)
241 min_generation
= curr_generation
;
243 if (paint_down_to_common(r
, array
[i
], filled
,
244 work
, min_generation
, 0, &common
)) {
245 clear_commit_marks(array
[i
], all_flags
);
246 clear_commit_marks_many(filled
, work
, all_flags
);
247 free_commit_list(common
);
253 if (array
[i
]->object
.flags
& PARENT2
)
255 for (j
= 0; j
< filled
; j
++)
256 if (work
[j
]->object
.flags
& PARENT1
)
257 redundant
[filled_index
[j
]] = 1;
258 clear_commit_marks(array
[i
], all_flags
);
259 clear_commit_marks_many(filled
, work
, all_flags
);
260 free_commit_list(common
);
263 /* Now collect the result */
264 COPY_ARRAY(work
, array
, cnt
);
265 for (i
= filled
= 0; i
< cnt
; i
++)
267 array
[filled
++] = work
[i
];
274 static int remove_redundant_with_gen(struct repository
*r
,
275 struct commit
**array
, int cnt
)
277 int i
, count_non_stale
= 0, count_still_independent
= cnt
;
278 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
279 struct commit
**walk_start
, **sorted
;
280 size_t walk_start_nr
= 0, walk_start_alloc
= cnt
;
284 * Sort the input by generation number, ascending. This allows
285 * us to increase the "min_generation" limit when we discover
286 * the commit with lowest generation is STALE. The index
287 * min_gen_pos points to the current position within 'array'
288 * that is not yet known to be STALE.
290 DUP_ARRAY(sorted
, array
, cnt
);
291 QSORT(sorted
, cnt
, compare_commits_by_gen
);
292 min_generation
= commit_graph_generation(sorted
[0]);
294 ALLOC_ARRAY(walk_start
, walk_start_alloc
);
296 /* Mark all parents of the input as STALE */
297 for (i
= 0; i
< cnt
; i
++) {
298 struct commit_list
*parents
;
300 repo_parse_commit(r
, array
[i
]);
301 array
[i
]->object
.flags
|= RESULT
;
302 parents
= array
[i
]->parents
;
305 repo_parse_commit(r
, parents
->item
);
306 if (!(parents
->item
->object
.flags
& STALE
)) {
307 parents
->item
->object
.flags
|= STALE
;
308 ALLOC_GROW(walk_start
, walk_start_nr
+ 1, walk_start_alloc
);
309 walk_start
[walk_start_nr
++] = parents
->item
;
311 parents
= parents
->next
;
315 QSORT(walk_start
, walk_start_nr
, compare_commits_by_gen
);
317 /* remove STALE bit for now to allow walking through parents */
318 for (i
= 0; i
< walk_start_nr
; i
++)
319 walk_start
[i
]->object
.flags
&= ~STALE
;
322 * Start walking from the highest generation. Hopefully, it will
323 * find all other items during the first-parent walk, and we can
324 * terminate early. Otherwise, we will do the same amount of work
327 for (i
= walk_start_nr
- 1; i
>= 0 && count_still_independent
> 1; i
--) {
328 /* push the STALE bits up to min generation */
329 struct commit_list
*stack
= NULL
;
331 commit_list_insert(walk_start
[i
], &stack
);
332 walk_start
[i
]->object
.flags
|= STALE
;
335 struct commit_list
*parents
;
336 struct commit
*c
= stack
->item
;
338 repo_parse_commit(r
, c
);
340 if (c
->object
.flags
& RESULT
) {
341 c
->object
.flags
&= ~RESULT
;
342 if (--count_still_independent
<= 1)
344 if (oideq(&c
->object
.oid
, &sorted
[min_gen_pos
]->object
.oid
)) {
345 while (min_gen_pos
< cnt
- 1 &&
346 (sorted
[min_gen_pos
]->object
.flags
& STALE
))
348 min_generation
= commit_graph_generation(sorted
[min_gen_pos
]);
352 if (commit_graph_generation(c
) < min_generation
) {
357 parents
= c
->parents
;
359 if (!(parents
->item
->object
.flags
& STALE
)) {
360 parents
->item
->object
.flags
|= STALE
;
361 commit_list_insert(parents
->item
, &stack
);
364 parents
= parents
->next
;
367 /* pop if all parents have been visited already */
371 free_commit_list(stack
);
376 for (i
= 0; i
< cnt
; i
++)
377 array
[i
]->object
.flags
&= ~RESULT
;
379 /* rearrange array */
380 for (i
= count_non_stale
= 0; i
< cnt
; i
++) {
381 if (!(array
[i
]->object
.flags
& STALE
))
382 array
[count_non_stale
++] = array
[i
];
386 clear_commit_marks_many(walk_start_nr
, walk_start
, STALE
);
389 return count_non_stale
;
392 static int remove_redundant(struct repository
*r
, struct commit
**array
, int cnt
)
395 * Some commit in the array may be an ancestor of
396 * another commit. Move the independent commits to the
397 * beginning of 'array' and return their number. Callers
398 * should not rely upon the contents of 'array' after
401 if (generation_numbers_enabled(r
)) {
405 * If we have a single commit with finite generation
406 * number, then the _with_gen algorithm is preferred.
408 for (i
= 0; i
< cnt
; i
++) {
409 if (commit_graph_generation(array
[i
]) < GENERATION_NUMBER_INFINITY
)
410 return remove_redundant_with_gen(r
, array
, cnt
);
414 return remove_redundant_no_gen(r
, array
, cnt
);
417 static int get_merge_bases_many_0(struct repository
*r
,
420 struct commit
**twos
,
422 struct commit_list
**result
)
424 struct commit_list
*list
;
425 struct commit
**rslt
;
428 if (merge_bases_many(r
, one
, n
, twos
, result
) < 0)
430 for (i
= 0; i
< n
; i
++) {
434 if (!*result
|| !(*result
)->next
) {
436 clear_commit_marks(one
, all_flags
);
437 clear_commit_marks_many(n
, twos
, all_flags
);
442 /* There are more than one */
443 cnt
= commit_list_count(*result
);
444 CALLOC_ARRAY(rslt
, cnt
);
445 for (list
= *result
, i
= 0; list
; list
= list
->next
)
446 rslt
[i
++] = list
->item
;
447 free_commit_list(*result
);
450 clear_commit_marks(one
, all_flags
);
451 clear_commit_marks_many(n
, twos
, all_flags
);
453 cnt
= remove_redundant(r
, rslt
, cnt
);
458 for (i
= 0; i
< cnt
; i
++)
459 commit_list_insert_by_date(rslt
[i
], result
);
464 int repo_get_merge_bases_many(struct repository
*r
,
467 struct commit
**twos
,
468 struct commit_list
**result
)
470 return get_merge_bases_many_0(r
, one
, n
, twos
, 1, result
);
473 int repo_get_merge_bases_many_dirty(struct repository
*r
,
476 struct commit
**twos
,
477 struct commit_list
**result
)
479 return get_merge_bases_many_0(r
, one
, n
, twos
, 0, result
);
482 int repo_get_merge_bases(struct repository
*r
,
485 struct commit_list
**result
)
487 return get_merge_bases_many_0(r
, one
, 1, &two
, 1, result
);
491 * Is "commit" a descendant of one of the elements on the "with_commit" list?
493 int repo_is_descendant_of(struct repository
*r
,
494 struct commit
*commit
,
495 struct commit_list
*with_commit
)
500 if (generation_numbers_enabled(r
)) {
501 struct commit_list
*from_list
= NULL
;
503 commit_list_insert(commit
, &from_list
);
504 result
= can_all_from_reach(from_list
, with_commit
, 0);
505 free_commit_list(from_list
);
508 while (with_commit
) {
509 struct commit
*other
;
512 other
= with_commit
->item
;
513 with_commit
= with_commit
->next
;
514 ret
= repo_in_merge_bases_many(r
, other
, 1, &commit
, 0);
523 * Is "commit" an ancestor of one of the "references"?
525 int repo_in_merge_bases_many(struct repository
*r
, struct commit
*commit
,
526 int nr_reference
, struct commit
**reference
,
527 int ignore_missing_commits
)
529 struct commit_list
*bases
= NULL
;
531 timestamp_t generation
, max_generation
= GENERATION_NUMBER_ZERO
;
533 if (repo_parse_commit(r
, commit
))
534 return ignore_missing_commits
? 0 : -1;
535 for (i
= 0; i
< nr_reference
; i
++) {
536 if (repo_parse_commit(r
, reference
[i
]))
537 return ignore_missing_commits
? 0 : -1;
539 generation
= commit_graph_generation(reference
[i
]);
540 if (generation
> max_generation
)
541 max_generation
= generation
;
544 generation
= commit_graph_generation(commit
);
545 if (generation
> max_generation
)
548 if (paint_down_to_common(r
, commit
,
549 nr_reference
, reference
,
550 generation
, ignore_missing_commits
, &bases
))
552 else if (commit
->object
.flags
& PARENT2
)
554 clear_commit_marks(commit
, all_flags
);
555 clear_commit_marks_many(nr_reference
, reference
, all_flags
);
556 free_commit_list(bases
);
561 * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
563 int repo_in_merge_bases(struct repository
*r
,
564 struct commit
*commit
,
565 struct commit
*reference
)
568 struct commit_list
*list
= NULL
;
569 struct commit_list
**next
= &list
;
571 next
= commit_list_append(commit
, next
);
572 res
= repo_is_descendant_of(r
, reference
, list
);
573 free_commit_list(list
);
578 struct commit_list
*reduce_heads(struct commit_list
*heads
)
580 struct commit_list
*p
;
581 struct commit_list
*result
= NULL
, **tail
= &result
;
582 struct commit
**array
;
589 for (p
= heads
; p
; p
= p
->next
)
590 p
->item
->object
.flags
&= ~STALE
;
591 for (p
= heads
, num_head
= 0; p
; p
= p
->next
) {
592 if (p
->item
->object
.flags
& STALE
)
594 p
->item
->object
.flags
|= STALE
;
597 CALLOC_ARRAY(array
, num_head
);
598 for (p
= heads
, i
= 0; p
; p
= p
->next
) {
599 if (p
->item
->object
.flags
& STALE
) {
600 array
[i
++] = p
->item
;
601 p
->item
->object
.flags
&= ~STALE
;
604 num_head
= remove_redundant(the_repository
, array
, num_head
);
609 for (i
= 0; i
< num_head
; i
++)
610 tail
= &commit_list_insert(array
[i
], tail
)->next
;
615 void reduce_heads_replace(struct commit_list
**heads
)
617 struct commit_list
*result
= reduce_heads(*heads
);
618 free_commit_list(*heads
);
622 int ref_newer(const struct object_id
*new_oid
, const struct object_id
*old_oid
)
625 struct commit
*old_commit
, *new_commit
;
626 struct commit_list
*old_commit_list
= NULL
;
630 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
631 * old_commit. Otherwise we require --force.
633 o
= deref_tag(the_repository
, parse_object(the_repository
, old_oid
),
635 if (!o
|| o
->type
!= OBJ_COMMIT
)
637 old_commit
= (struct commit
*) o
;
639 o
= deref_tag(the_repository
, parse_object(the_repository
, new_oid
),
641 if (!o
|| o
->type
!= OBJ_COMMIT
)
643 new_commit
= (struct commit
*) o
;
645 if (repo_parse_commit(the_repository
, new_commit
) < 0)
648 commit_list_insert(old_commit
, &old_commit_list
);
649 ret
= repo_is_descendant_of(the_repository
,
650 new_commit
, old_commit_list
);
653 free_commit_list(old_commit_list
);
658 * Mimicking the real stack, this stack lives on the heap, avoiding stack
661 * At each recursion step, the stack items points to the commits whose
662 * ancestors are to be inspected.
664 struct contains_stack
{
666 struct contains_stack_entry
{
667 struct commit
*commit
;
668 struct commit_list
*parents
;
672 static int in_commit_list(const struct commit_list
*want
, struct commit
*c
)
674 for (; want
; want
= want
->next
)
675 if (oideq(&want
->item
->object
.oid
, &c
->object
.oid
))
681 * Test whether the candidate is contained in the list.
682 * Do not recurse to find out, though, but return -1 if inconclusive.
684 static enum contains_result
contains_test(struct commit
*candidate
,
685 const struct commit_list
*want
,
686 struct contains_cache
*cache
,
689 enum contains_result
*cached
= contains_cache_at(cache
, candidate
);
691 /* If we already have the answer cached, return that. */
696 if (in_commit_list(want
, candidate
)) {
697 *cached
= CONTAINS_YES
;
701 /* Otherwise, we don't know; prepare to recurse */
702 parse_commit_or_die(candidate
);
704 if (commit_graph_generation(candidate
) < cutoff
)
707 return CONTAINS_UNKNOWN
;
710 static void push_to_contains_stack(struct commit
*candidate
, struct contains_stack
*contains_stack
)
712 ALLOC_GROW(contains_stack
->contains_stack
, contains_stack
->nr
+ 1, contains_stack
->alloc
);
713 contains_stack
->contains_stack
[contains_stack
->nr
].commit
= candidate
;
714 contains_stack
->contains_stack
[contains_stack
->nr
++].parents
= candidate
->parents
;
717 static enum contains_result
contains_tag_algo(struct commit
*candidate
,
718 const struct commit_list
*want
,
719 struct contains_cache
*cache
)
721 struct contains_stack contains_stack
= { 0, 0, NULL
};
722 enum contains_result result
;
723 timestamp_t cutoff
= GENERATION_NUMBER_INFINITY
;
724 const struct commit_list
*p
;
726 for (p
= want
; p
; p
= p
->next
) {
727 timestamp_t generation
;
728 struct commit
*c
= p
->item
;
729 load_commit_graph_info(the_repository
, c
);
730 generation
= commit_graph_generation(c
);
731 if (generation
< cutoff
)
735 result
= contains_test(candidate
, want
, cache
, cutoff
);
736 if (result
!= CONTAINS_UNKNOWN
)
739 push_to_contains_stack(candidate
, &contains_stack
);
740 while (contains_stack
.nr
) {
741 struct contains_stack_entry
*entry
= &contains_stack
.contains_stack
[contains_stack
.nr
- 1];
742 struct commit
*commit
= entry
->commit
;
743 struct commit_list
*parents
= entry
->parents
;
746 *contains_cache_at(cache
, commit
) = CONTAINS_NO
;
750 * If we just popped the stack, parents->item has been marked,
751 * therefore contains_test will return a meaningful yes/no.
753 else switch (contains_test(parents
->item
, want
, cache
, cutoff
)) {
755 *contains_cache_at(cache
, commit
) = CONTAINS_YES
;
759 entry
->parents
= parents
->next
;
761 case CONTAINS_UNKNOWN
:
762 push_to_contains_stack(parents
->item
, &contains_stack
);
766 free(contains_stack
.contains_stack
);
767 return contains_test(candidate
, want
, cache
, cutoff
);
770 int commit_contains(struct ref_filter
*filter
, struct commit
*commit
,
771 struct commit_list
*list
, struct contains_cache
*cache
)
773 if (filter
->with_commit_tag_algo
)
774 return contains_tag_algo(commit
, list
, cache
) == CONTAINS_YES
;
775 return repo_is_descendant_of(the_repository
, commit
, list
);
778 int can_all_from_reach_with_flag(struct object_array
*from
,
779 unsigned int with_flag
,
780 unsigned int assign_flag
,
781 time_t min_commit_date
,
782 timestamp_t min_generation
)
784 struct commit
**list
= NULL
;
789 ALLOC_ARRAY(list
, from
->nr
);
791 for (i
= 0; i
< from
->nr
; i
++) {
792 struct object
*from_one
= from
->objects
[i
].item
;
794 if (!from_one
|| from_one
->flags
& assign_flag
)
797 from_one
= deref_tag(the_repository
, from_one
,
799 if (!from_one
|| from_one
->type
!= OBJ_COMMIT
) {
801 * no way to tell if this is reachable by
802 * looking at the ancestry chain alone, so
803 * leave a note to ourselves not to worry about
804 * this object anymore.
806 from
->objects
[i
].item
->flags
|= assign_flag
;
810 list
[nr_commits
] = (struct commit
*)from_one
;
811 if (repo_parse_commit(the_repository
, list
[nr_commits
]) ||
812 commit_graph_generation(list
[nr_commits
]) < min_generation
) {
820 QSORT(list
, nr_commits
, compare_commits_by_gen
);
822 for (i
= 0; i
< nr_commits
; i
++) {
823 /* DFS from list[i] */
824 struct commit_list
*stack
= NULL
;
826 list
[i
]->object
.flags
|= assign_flag
;
827 commit_list_insert(list
[i
], &stack
);
830 struct commit_list
*parent
;
832 if (stack
->item
->object
.flags
& (with_flag
| RESULT
)) {
835 stack
->item
->object
.flags
|= RESULT
;
839 for (parent
= stack
->item
->parents
; parent
; parent
= parent
->next
) {
840 if (parent
->item
->object
.flags
& (with_flag
| RESULT
))
841 stack
->item
->object
.flags
|= RESULT
;
843 if (!(parent
->item
->object
.flags
& assign_flag
)) {
844 parent
->item
->object
.flags
|= assign_flag
;
846 if (repo_parse_commit(the_repository
, parent
->item
) ||
847 parent
->item
->date
< min_commit_date
||
848 commit_graph_generation(parent
->item
) < min_generation
)
851 commit_list_insert(parent
->item
, &stack
);
860 if (!(list
[i
]->object
.flags
& (with_flag
| RESULT
))) {
867 clear_commit_marks_many(nr_commits
, list
, RESULT
| assign_flag
);
870 for (i
= 0; i
< from
->nr
; i
++) {
871 struct object
*from_one
= from
->objects
[i
].item
;
874 from_one
->flags
&= ~assign_flag
;
880 int can_all_from_reach(struct commit_list
*from
, struct commit_list
*to
,
881 int cutoff_by_min_date
)
883 struct object_array from_objs
= OBJECT_ARRAY_INIT
;
884 time_t min_commit_date
= cutoff_by_min_date
? from
->item
->date
: 0;
885 struct commit_list
*from_iter
= from
, *to_iter
= to
;
887 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
890 add_object_array(&from_iter
->item
->object
, NULL
, &from_objs
);
892 if (!repo_parse_commit(the_repository
, from_iter
->item
)) {
893 timestamp_t generation
;
894 if (from_iter
->item
->date
< min_commit_date
)
895 min_commit_date
= from_iter
->item
->date
;
897 generation
= commit_graph_generation(from_iter
->item
);
898 if (generation
< min_generation
)
899 min_generation
= generation
;
902 from_iter
= from_iter
->next
;
906 if (!repo_parse_commit(the_repository
, to_iter
->item
)) {
907 timestamp_t generation
;
908 if (to_iter
->item
->date
< min_commit_date
)
909 min_commit_date
= to_iter
->item
->date
;
911 generation
= commit_graph_generation(to_iter
->item
);
912 if (generation
< min_generation
)
913 min_generation
= generation
;
916 to_iter
->item
->object
.flags
|= PARENT2
;
918 to_iter
= to_iter
->next
;
921 result
= can_all_from_reach_with_flag(&from_objs
, PARENT2
, PARENT1
,
922 min_commit_date
, min_generation
);
925 clear_commit_marks(from
->item
, PARENT1
);
930 clear_commit_marks(to
->item
, PARENT2
);
934 object_array_clear(&from_objs
);
938 struct commit_list
*get_reachable_subset(struct commit
**from
, int nr_from
,
939 struct commit
**to
, int nr_to
,
940 unsigned int reachable_flag
)
942 struct commit
**item
;
943 struct commit
*current
;
944 struct commit_list
*found_commits
= NULL
;
945 struct commit
**to_last
= to
+ nr_to
;
946 struct commit
**from_last
= from
+ nr_from
;
947 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
950 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
952 for (item
= to
; item
< to_last
; item
++) {
953 timestamp_t generation
;
954 struct commit
*c
= *item
;
956 repo_parse_commit(the_repository
, c
);
957 generation
= commit_graph_generation(c
);
958 if (generation
< min_generation
)
959 min_generation
= generation
;
961 if (!(c
->object
.flags
& PARENT1
)) {
962 c
->object
.flags
|= PARENT1
;
967 for (item
= from
; item
< from_last
; item
++) {
968 struct commit
*c
= *item
;
969 if (!(c
->object
.flags
& PARENT2
)) {
970 c
->object
.flags
|= PARENT2
;
971 repo_parse_commit(the_repository
, c
);
973 prio_queue_put(&queue
, *item
);
977 while (num_to_find
&& (current
= prio_queue_get(&queue
)) != NULL
) {
978 struct commit_list
*parents
;
980 if (current
->object
.flags
& PARENT1
) {
981 current
->object
.flags
&= ~PARENT1
;
982 current
->object
.flags
|= reachable_flag
;
983 commit_list_insert(current
, &found_commits
);
987 for (parents
= current
->parents
; parents
; parents
= parents
->next
) {
988 struct commit
*p
= parents
->item
;
990 repo_parse_commit(the_repository
, p
);
992 if (commit_graph_generation(p
) < min_generation
)
995 if (p
->object
.flags
& PARENT2
)
998 p
->object
.flags
|= PARENT2
;
999 prio_queue_put(&queue
, p
);
1003 clear_prio_queue(&queue
);
1005 clear_commit_marks_many(nr_to
, to
, PARENT1
);
1006 clear_commit_marks_many(nr_from
, from
, PARENT2
);
1008 return found_commits
;
1011 define_commit_slab(bit_arrays
, struct bitmap
*);
1012 static struct bit_arrays bit_arrays
;
1014 static void insert_no_dup(struct prio_queue
*queue
, struct commit
*c
)
1016 if (c
->object
.flags
& PARENT2
)
1018 prio_queue_put(queue
, c
);
1019 c
->object
.flags
|= PARENT2
;
1022 static struct bitmap
*get_bit_array(struct commit
*c
, int width
)
1024 struct bitmap
**bitmap
= bit_arrays_at(&bit_arrays
, c
);
1026 *bitmap
= bitmap_word_alloc(width
);
1030 static void free_bit_array(struct commit
*c
)
1032 struct bitmap
**bitmap
= bit_arrays_at(&bit_arrays
, c
);
1035 bitmap_free(*bitmap
);
1039 void ahead_behind(struct repository
*r
,
1040 struct commit
**commits
, size_t commits_nr
,
1041 struct ahead_behind_count
*counts
, size_t counts_nr
)
1043 struct prio_queue queue
= { .compare
= compare_commits_by_gen_then_commit_date
};
1044 size_t width
= DIV_ROUND_UP(commits_nr
, BITS_IN_EWORD
);
1046 if (!commits_nr
|| !counts_nr
)
1049 for (size_t i
= 0; i
< counts_nr
; i
++) {
1050 counts
[i
].ahead
= 0;
1051 counts
[i
].behind
= 0;
1054 ensure_generations_valid(r
, commits
, commits_nr
);
1056 init_bit_arrays(&bit_arrays
);
1058 for (size_t i
= 0; i
< commits_nr
; i
++) {
1059 struct commit
*c
= commits
[i
];
1060 struct bitmap
*bitmap
= get_bit_array(c
, width
);
1062 bitmap_set(bitmap
, i
);
1063 insert_no_dup(&queue
, c
);
1066 while (queue_has_nonstale(&queue
)) {
1067 struct commit
*c
= prio_queue_get(&queue
);
1068 struct commit_list
*p
;
1069 struct bitmap
*bitmap_c
= get_bit_array(c
, width
);
1071 for (size_t i
= 0; i
< counts_nr
; i
++) {
1072 int reach_from_tip
= !!bitmap_get(bitmap_c
, counts
[i
].tip_index
);
1073 int reach_from_base
= !!bitmap_get(bitmap_c
, counts
[i
].base_index
);
1075 if (reach_from_tip
^ reach_from_base
) {
1076 if (reach_from_base
)
1083 for (p
= c
->parents
; p
; p
= p
->next
) {
1084 struct bitmap
*bitmap_p
;
1086 repo_parse_commit(r
, p
->item
);
1088 bitmap_p
= get_bit_array(p
->item
, width
);
1089 bitmap_or(bitmap_p
, bitmap_c
);
1092 * If this parent is reachable from every starting
1093 * commit, then none of its ancestors can contribute
1094 * to the ahead/behind count. Mark it as STALE, so
1095 * we can stop the walk when every commit in the
1098 if (bitmap_popcount(bitmap_p
) == commits_nr
)
1099 p
->item
->object
.flags
|= STALE
;
1101 insert_no_dup(&queue
, p
->item
);
1107 /* STALE is used here, PARENT2 is used by insert_no_dup(). */
1108 repo_clear_commit_marks(r
, PARENT2
| STALE
);
1109 while (prio_queue_peek(&queue
)) {
1110 struct commit
*c
= prio_queue_get(&queue
);
1113 clear_bit_arrays(&bit_arrays
);
1114 clear_prio_queue(&queue
);
1117 struct commit_and_index
{
1118 struct commit
*commit
;
1120 timestamp_t generation
;
1123 static int compare_commit_and_index_by_generation(const void *va
, const void *vb
)
1125 const struct commit_and_index
*a
= (const struct commit_and_index
*)va
;
1126 const struct commit_and_index
*b
= (const struct commit_and_index
*)vb
;
1128 if (a
->generation
> b
->generation
)
1130 if (a
->generation
< b
->generation
)
1135 void tips_reachable_from_bases(struct repository
*r
,
1136 struct commit_list
*bases
,
1137 struct commit
**tips
, size_t tips_nr
,
1140 struct commit_and_index
*commits
;
1141 size_t min_generation_index
= 0;
1142 timestamp_t min_generation
;
1143 struct commit_list
*stack
= NULL
;
1145 if (!bases
|| !tips
|| !tips_nr
)
1149 * Do a depth-first search starting at 'bases' to search for the
1150 * tips. Stop at the lowest (un-found) generation number. When
1151 * finding the lowest commit, increase the minimum generation
1152 * number to the next lowest (un-found) generation number.
1155 CALLOC_ARRAY(commits
, tips_nr
);
1157 for (size_t i
= 0; i
< tips_nr
; i
++) {
1158 commits
[i
].commit
= tips
[i
];
1159 commits
[i
].index
= i
;
1160 commits
[i
].generation
= commit_graph_generation(tips
[i
]);
1163 /* Sort with generation number ascending. */
1164 QSORT(commits
, tips_nr
, compare_commit_and_index_by_generation
);
1165 min_generation
= commits
[0].generation
;
1168 repo_parse_commit(r
, bases
->item
);
1169 commit_list_insert(bases
->item
, &stack
);
1170 bases
= bases
->next
;
1174 int explored_all_parents
= 1;
1175 struct commit_list
*p
;
1176 struct commit
*c
= stack
->item
;
1177 timestamp_t c_gen
= commit_graph_generation(c
);
1179 /* Does it match any of our tips? */
1180 for (size_t j
= min_generation_index
; j
< tips_nr
; j
++) {
1181 if (c_gen
< commits
[j
].generation
)
1184 if (commits
[j
].commit
== c
) {
1185 tips
[commits
[j
].index
]->object
.flags
|= mark
;
1187 if (j
== min_generation_index
) {
1188 unsigned int k
= j
+ 1;
1189 while (k
< tips_nr
&&
1190 (tips
[commits
[k
].index
]->object
.flags
& mark
))
1193 /* Terminate early if all found. */
1197 min_generation_index
= k
;
1198 min_generation
= commits
[k
].generation
;
1203 for (p
= c
->parents
; p
; p
= p
->next
) {
1204 repo_parse_commit(r
, p
->item
);
1206 /* Have we already explored this parent? */
1207 if (p
->item
->object
.flags
& SEEN
)
1210 /* Is it below the current minimum generation? */
1211 if (commit_graph_generation(p
->item
) < min_generation
)
1214 /* Ok, we will explore from here on. */
1215 p
->item
->object
.flags
|= SEEN
;
1216 explored_all_parents
= 0;
1217 commit_list_insert(p
->item
, &stack
);
1221 if (explored_all_parents
)
1227 repo_clear_commit_marks(r
, SEEN
);