1 #define USE_THE_REPOSITORY_VARIABLE
3 #include "git-compat-util.h"
5 #include "commit-graph.h"
8 #include "prio-queue.h"
9 #include "ref-filter.h"
12 #include "commit-reach.h"
13 #include "ewah/ewok.h"
15 /* Remember to update object flag allocation in object.h */
16 #define PARENT1 (1u<<16)
17 #define PARENT2 (1u<<17)
18 #define STALE (1u<<18)
19 #define RESULT (1u<<19)
21 static const unsigned all_flags
= (PARENT1
| PARENT2
| STALE
| RESULT
);
23 static int compare_commits_by_gen(const void *_a
, const void *_b
)
25 const struct commit
*a
= *(const struct commit
* const *)_a
;
26 const struct commit
*b
= *(const struct commit
* const *)_b
;
28 timestamp_t generation_a
= commit_graph_generation(a
);
29 timestamp_t generation_b
= commit_graph_generation(b
);
31 if (generation_a
< generation_b
)
33 if (generation_a
> generation_b
)
35 if (a
->date
< b
->date
)
37 if (a
->date
> b
->date
)
42 static int queue_has_nonstale(struct prio_queue
*queue
)
44 for (size_t 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 int paint_down_to_common(struct repository
*r
,
54 struct commit
*one
, int n
,
56 timestamp_t min_generation
,
57 int ignore_missing_commits
,
58 struct commit_list
**result
)
60 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
62 timestamp_t last_gen
= GENERATION_NUMBER_INFINITY
;
64 if (!min_generation
&& !corrected_commit_dates_enabled(r
))
65 queue
.compare
= compare_commits_by_commit_date
;
67 one
->object
.flags
|= PARENT1
;
69 commit_list_append(one
, result
);
72 prio_queue_put(&queue
, one
);
74 for (i
= 0; i
< n
; i
++) {
75 twos
[i
]->object
.flags
|= PARENT2
;
76 prio_queue_put(&queue
, twos
[i
]);
79 while (queue_has_nonstale(&queue
)) {
80 struct commit
*commit
= prio_queue_get(&queue
);
81 struct commit_list
*parents
;
83 timestamp_t generation
= commit_graph_generation(commit
);
85 if (min_generation
&& generation
> last_gen
)
86 BUG("bad generation skip %"PRItime
" > %"PRItime
" at %s",
88 oid_to_hex(&commit
->object
.oid
));
89 last_gen
= generation
;
91 if (generation
< min_generation
)
94 flags
= commit
->object
.flags
& (PARENT1
| PARENT2
| STALE
);
95 if (flags
== (PARENT1
| PARENT2
)) {
96 if (!(commit
->object
.flags
& RESULT
)) {
97 commit
->object
.flags
|= RESULT
;
98 commit_list_insert_by_date(commit
, result
);
100 /* Mark parents of a found merge stale */
103 parents
= commit
->parents
;
105 struct commit
*p
= parents
->item
;
106 parents
= parents
->next
;
107 if ((p
->object
.flags
& flags
) == flags
)
109 if (repo_parse_commit(r
, p
)) {
110 clear_prio_queue(&queue
);
111 free_commit_list(*result
);
114 * At this stage, we know that the commit is
115 * missing: `repo_parse_commit()` uses
116 * `OBJECT_INFO_DIE_IF_CORRUPT` and therefore
117 * corrupt commits would already have been
118 * dispatched with a `die()`.
120 if (ignore_missing_commits
)
122 return error(_("could not parse commit %s"),
123 oid_to_hex(&p
->object
.oid
));
125 p
->object
.flags
|= flags
;
126 prio_queue_put(&queue
, p
);
130 clear_prio_queue(&queue
);
134 static int merge_bases_many(struct repository
*r
,
135 struct commit
*one
, int n
,
136 struct commit
**twos
,
137 struct commit_list
**result
)
139 struct commit_list
*list
= NULL
;
142 for (i
= 0; i
< n
; i
++) {
143 if (one
== twos
[i
]) {
145 * We do not mark this even with RESULT so we do not
146 * have to clean it up.
148 *result
= commit_list_insert(one
, result
);
155 if (repo_parse_commit(r
, one
))
156 return error(_("could not parse commit %s"),
157 oid_to_hex(&one
->object
.oid
));
158 for (i
= 0; i
< n
; i
++) {
161 if (repo_parse_commit(r
, twos
[i
]))
162 return error(_("could not parse commit %s"),
163 oid_to_hex(&twos
[i
]->object
.oid
));
166 if (paint_down_to_common(r
, one
, n
, twos
, 0, 0, &list
)) {
167 free_commit_list(list
);
172 struct commit
*commit
= pop_commit(&list
);
173 if (!(commit
->object
.flags
& STALE
))
174 commit_list_insert_by_date(commit
, result
);
179 int get_octopus_merge_bases(struct commit_list
*in
, struct commit_list
**result
)
181 struct commit_list
*i
, *j
, *k
;
186 commit_list_insert(in
->item
, result
);
188 for (i
= in
->next
; i
; i
= i
->next
) {
189 struct commit_list
*new_commits
= NULL
, *end
= NULL
;
191 for (j
= *result
; j
; j
= j
->next
) {
192 struct commit_list
*bases
= NULL
;
193 if (repo_get_merge_bases(the_repository
, i
->item
,
194 j
->item
, &bases
) < 0) {
195 free_commit_list(bases
);
196 free_commit_list(*result
);
204 for (k
= bases
; k
; k
= k
->next
)
207 free_commit_list(*result
);
208 *result
= new_commits
;
213 static int remove_redundant_no_gen(struct repository
*r
,
214 struct commit
**array
,
215 size_t cnt
, size_t *dedup_cnt
)
217 struct commit
**work
;
218 unsigned char *redundant
;
219 size_t *filled_index
;
222 CALLOC_ARRAY(work
, cnt
);
223 redundant
= xcalloc(cnt
, 1);
224 ALLOC_ARRAY(filled_index
, cnt
- 1);
226 for (i
= 0; i
< cnt
; i
++)
227 repo_parse_commit(r
, array
[i
]);
228 for (i
= 0; i
< cnt
; i
++) {
229 struct commit_list
*common
= NULL
;
230 timestamp_t min_generation
= commit_graph_generation(array
[i
]);
234 for (j
= filled
= 0; j
< cnt
; j
++) {
235 timestamp_t curr_generation
;
236 if (i
== j
|| redundant
[j
])
238 filled_index
[filled
] = j
;
239 work
[filled
++] = array
[j
];
241 curr_generation
= commit_graph_generation(array
[j
]);
242 if (curr_generation
< min_generation
)
243 min_generation
= curr_generation
;
245 if (paint_down_to_common(r
, array
[i
], filled
,
246 work
, min_generation
, 0, &common
)) {
247 clear_commit_marks(array
[i
], all_flags
);
248 clear_commit_marks_many(filled
, work
, all_flags
);
249 free_commit_list(common
);
255 if (array
[i
]->object
.flags
& PARENT2
)
257 for (j
= 0; j
< filled
; j
++)
258 if (work
[j
]->object
.flags
& PARENT1
)
259 redundant
[filled_index
[j
]] = 1;
260 clear_commit_marks(array
[i
], all_flags
);
261 clear_commit_marks_many(filled
, work
, all_flags
);
262 free_commit_list(common
);
265 /* Now collect the result */
266 COPY_ARRAY(work
, array
, cnt
);
267 for (i
= filled
= 0; i
< cnt
; i
++)
269 array
[filled
++] = work
[i
];
277 static int remove_redundant_with_gen(struct repository
*r
,
278 struct commit
**array
, size_t cnt
,
281 size_t i
, count_non_stale
= 0, count_still_independent
= cnt
;
282 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
283 struct commit
**walk_start
, **sorted
;
284 size_t walk_start_nr
= 0, walk_start_alloc
= cnt
;
285 size_t min_gen_pos
= 0;
288 * Sort the input by generation number, ascending. This allows
289 * us to increase the "min_generation" limit when we discover
290 * the commit with lowest generation is STALE. The index
291 * min_gen_pos points to the current position within 'array'
292 * that is not yet known to be STALE.
294 DUP_ARRAY(sorted
, array
, cnt
);
295 QSORT(sorted
, cnt
, compare_commits_by_gen
);
296 min_generation
= commit_graph_generation(sorted
[0]);
298 ALLOC_ARRAY(walk_start
, walk_start_alloc
);
300 /* Mark all parents of the input as STALE */
301 for (i
= 0; i
< cnt
; i
++) {
302 struct commit_list
*parents
;
304 repo_parse_commit(r
, array
[i
]);
305 array
[i
]->object
.flags
|= RESULT
;
306 parents
= array
[i
]->parents
;
309 repo_parse_commit(r
, parents
->item
);
310 if (!(parents
->item
->object
.flags
& STALE
)) {
311 parents
->item
->object
.flags
|= STALE
;
312 ALLOC_GROW(walk_start
, walk_start_nr
+ 1, walk_start_alloc
);
313 walk_start
[walk_start_nr
++] = parents
->item
;
315 parents
= parents
->next
;
319 QSORT(walk_start
, walk_start_nr
, compare_commits_by_gen
);
321 /* remove STALE bit for now to allow walking through parents */
322 for (i
= 0; i
< walk_start_nr
; i
++)
323 walk_start
[i
]->object
.flags
&= ~STALE
;
326 * Start walking from the highest generation. Hopefully, it will
327 * find all other items during the first-parent walk, and we can
328 * terminate early. Otherwise, we will do the same amount of work
331 for (i
= walk_start_nr
; i
&& count_still_independent
> 1; i
--) {
332 /* push the STALE bits up to min generation */
333 struct commit_list
*stack
= NULL
;
335 commit_list_insert(walk_start
[i
- 1], &stack
);
336 walk_start
[i
- 1]->object
.flags
|= STALE
;
339 struct commit_list
*parents
;
340 struct commit
*c
= stack
->item
;
342 repo_parse_commit(r
, c
);
344 if (c
->object
.flags
& RESULT
) {
345 c
->object
.flags
&= ~RESULT
;
346 if (--count_still_independent
<= 1)
348 if (oideq(&c
->object
.oid
, &sorted
[min_gen_pos
]->object
.oid
)) {
349 while (min_gen_pos
< cnt
- 1 &&
350 (sorted
[min_gen_pos
]->object
.flags
& STALE
))
352 min_generation
= commit_graph_generation(sorted
[min_gen_pos
]);
356 if (commit_graph_generation(c
) < min_generation
) {
361 parents
= c
->parents
;
363 if (!(parents
->item
->object
.flags
& STALE
)) {
364 parents
->item
->object
.flags
|= STALE
;
365 commit_list_insert(parents
->item
, &stack
);
368 parents
= parents
->next
;
371 /* pop if all parents have been visited already */
375 free_commit_list(stack
);
380 for (i
= 0; i
< cnt
; i
++)
381 array
[i
]->object
.flags
&= ~RESULT
;
383 /* rearrange array */
384 for (i
= count_non_stale
= 0; i
< cnt
; i
++) {
385 if (!(array
[i
]->object
.flags
& STALE
))
386 array
[count_non_stale
++] = array
[i
];
390 clear_commit_marks_many(walk_start_nr
, walk_start
, STALE
);
393 *dedup_cnt
= count_non_stale
;
397 static int remove_redundant(struct repository
*r
, struct commit
**array
,
398 size_t cnt
, size_t *dedup_cnt
)
401 * Some commit in the array may be an ancestor of
402 * another commit. Move the independent commits to the
403 * beginning of 'array' and return their number. Callers
404 * should not rely upon the contents of 'array' after
407 if (generation_numbers_enabled(r
)) {
409 * If we have a single commit with finite generation
410 * number, then the _with_gen algorithm is preferred.
412 for (size_t i
= 0; i
< cnt
; i
++) {
413 if (commit_graph_generation(array
[i
]) < GENERATION_NUMBER_INFINITY
)
414 return remove_redundant_with_gen(r
, array
, cnt
, dedup_cnt
);
418 return remove_redundant_no_gen(r
, array
, cnt
, dedup_cnt
);
421 static int get_merge_bases_many_0(struct repository
*r
,
424 struct commit
**twos
,
426 struct commit_list
**result
)
428 struct commit_list
*list
;
429 struct commit
**rslt
;
433 if (merge_bases_many(r
, one
, n
, twos
, result
) < 0)
435 for (i
= 0; i
< n
; i
++) {
439 if (!*result
|| !(*result
)->next
) {
441 clear_commit_marks(one
, all_flags
);
442 clear_commit_marks_many(n
, twos
, all_flags
);
447 /* There are more than one */
448 cnt
= commit_list_count(*result
);
449 CALLOC_ARRAY(rslt
, cnt
);
450 for (list
= *result
, i
= 0; list
; list
= list
->next
)
451 rslt
[i
++] = list
->item
;
452 free_commit_list(*result
);
455 clear_commit_marks(one
, all_flags
);
456 clear_commit_marks_many(n
, twos
, all_flags
);
458 ret
= remove_redundant(r
, rslt
, cnt
, &cnt
);
463 for (i
= 0; i
< cnt
; i
++)
464 commit_list_insert_by_date(rslt
[i
], result
);
469 int repo_get_merge_bases_many(struct repository
*r
,
472 struct commit
**twos
,
473 struct commit_list
**result
)
475 return get_merge_bases_many_0(r
, one
, n
, twos
, 1, result
);
478 int repo_get_merge_bases_many_dirty(struct repository
*r
,
481 struct commit
**twos
,
482 struct commit_list
**result
)
484 return get_merge_bases_many_0(r
, one
, n
, twos
, 0, result
);
487 int repo_get_merge_bases(struct repository
*r
,
490 struct commit_list
**result
)
492 return get_merge_bases_many_0(r
, one
, 1, &two
, 1, result
);
496 * Is "commit" a descendant of one of the elements on the "with_commit" list?
498 int repo_is_descendant_of(struct repository
*r
,
499 struct commit
*commit
,
500 struct commit_list
*with_commit
)
505 if (generation_numbers_enabled(r
)) {
506 struct commit_list
*from_list
= NULL
;
508 commit_list_insert(commit
, &from_list
);
509 result
= can_all_from_reach(from_list
, with_commit
, 0);
510 free_commit_list(from_list
);
513 while (with_commit
) {
514 struct commit
*other
;
517 other
= with_commit
->item
;
518 with_commit
= with_commit
->next
;
519 ret
= repo_in_merge_bases_many(r
, other
, 1, &commit
, 0);
528 * Is "commit" an ancestor of one of the "references"?
530 int repo_in_merge_bases_many(struct repository
*r
, struct commit
*commit
,
531 int nr_reference
, struct commit
**reference
,
532 int ignore_missing_commits
)
534 struct commit_list
*bases
= NULL
;
536 timestamp_t generation
, max_generation
= GENERATION_NUMBER_ZERO
;
538 if (repo_parse_commit(r
, commit
))
539 return ignore_missing_commits
? 0 : -1;
540 for (i
= 0; i
< nr_reference
; i
++) {
541 if (repo_parse_commit(r
, reference
[i
]))
542 return ignore_missing_commits
? 0 : -1;
544 generation
= commit_graph_generation(reference
[i
]);
545 if (generation
> max_generation
)
546 max_generation
= generation
;
549 generation
= commit_graph_generation(commit
);
550 if (generation
> max_generation
)
553 if (paint_down_to_common(r
, commit
,
554 nr_reference
, reference
,
555 generation
, ignore_missing_commits
, &bases
))
557 else if (commit
->object
.flags
& PARENT2
)
559 clear_commit_marks(commit
, all_flags
);
560 clear_commit_marks_many(nr_reference
, reference
, all_flags
);
561 free_commit_list(bases
);
566 * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
568 int repo_in_merge_bases(struct repository
*r
,
569 struct commit
*commit
,
570 struct commit
*reference
)
573 struct commit_list
*list
= NULL
;
574 struct commit_list
**next
= &list
;
576 next
= commit_list_append(commit
, next
);
577 res
= repo_is_descendant_of(r
, reference
, list
);
578 free_commit_list(list
);
583 struct commit_list
*reduce_heads(struct commit_list
*heads
)
585 struct commit_list
*p
;
586 struct commit_list
*result
= NULL
, **tail
= &result
;
587 struct commit
**array
;
595 for (p
= heads
; p
; p
= p
->next
)
596 p
->item
->object
.flags
&= ~STALE
;
597 for (p
= heads
, num_head
= 0; p
; p
= p
->next
) {
598 if (p
->item
->object
.flags
& STALE
)
600 p
->item
->object
.flags
|= STALE
;
603 CALLOC_ARRAY(array
, num_head
);
604 for (p
= heads
, i
= 0; p
; p
= p
->next
) {
605 if (p
->item
->object
.flags
& STALE
) {
606 array
[i
++] = p
->item
;
607 p
->item
->object
.flags
&= ~STALE
;
611 ret
= remove_redundant(the_repository
, array
, num_head
, &num_head
);
617 for (i
= 0; i
< num_head
; i
++)
618 tail
= &commit_list_insert(array
[i
], tail
)->next
;
623 void reduce_heads_replace(struct commit_list
**heads
)
625 struct commit_list
*result
= reduce_heads(*heads
);
626 free_commit_list(*heads
);
630 int ref_newer(const struct object_id
*new_oid
, const struct object_id
*old_oid
)
633 struct commit
*old_commit
, *new_commit
;
634 struct commit_list
*old_commit_list
= NULL
;
638 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
639 * old_commit. Otherwise we require --force.
641 o
= deref_tag(the_repository
, parse_object(the_repository
, old_oid
),
643 if (!o
|| o
->type
!= OBJ_COMMIT
)
645 old_commit
= (struct commit
*) o
;
647 o
= deref_tag(the_repository
, parse_object(the_repository
, new_oid
),
649 if (!o
|| o
->type
!= OBJ_COMMIT
)
651 new_commit
= (struct commit
*) o
;
653 if (repo_parse_commit(the_repository
, new_commit
) < 0)
656 commit_list_insert(old_commit
, &old_commit_list
);
657 ret
= repo_is_descendant_of(the_repository
,
658 new_commit
, old_commit_list
);
661 free_commit_list(old_commit_list
);
666 * Mimicking the real stack, this stack lives on the heap, avoiding stack
669 * At each recursion step, the stack items points to the commits whose
670 * ancestors are to be inspected.
672 struct contains_stack
{
674 struct contains_stack_entry
{
675 struct commit
*commit
;
676 struct commit_list
*parents
;
680 static int in_commit_list(const struct commit_list
*want
, struct commit
*c
)
682 for (; want
; want
= want
->next
)
683 if (oideq(&want
->item
->object
.oid
, &c
->object
.oid
))
689 * Test whether the candidate is contained in the list.
690 * Do not recurse to find out, though, but return -1 if inconclusive.
692 static enum contains_result
contains_test(struct commit
*candidate
,
693 const struct commit_list
*want
,
694 struct contains_cache
*cache
,
697 enum contains_result
*cached
= contains_cache_at(cache
, candidate
);
699 /* If we already have the answer cached, return that. */
704 if (in_commit_list(want
, candidate
)) {
705 *cached
= CONTAINS_YES
;
709 /* Otherwise, we don't know; prepare to recurse */
710 parse_commit_or_die(candidate
);
712 if (commit_graph_generation(candidate
) < cutoff
)
715 return CONTAINS_UNKNOWN
;
718 static void push_to_contains_stack(struct commit
*candidate
, struct contains_stack
*contains_stack
)
720 ALLOC_GROW(contains_stack
->contains_stack
, contains_stack
->nr
+ 1, contains_stack
->alloc
);
721 contains_stack
->contains_stack
[contains_stack
->nr
].commit
= candidate
;
722 contains_stack
->contains_stack
[contains_stack
->nr
++].parents
= candidate
->parents
;
725 static enum contains_result
contains_tag_algo(struct commit
*candidate
,
726 const struct commit_list
*want
,
727 struct contains_cache
*cache
)
729 struct contains_stack contains_stack
= { 0, 0, NULL
};
730 enum contains_result result
;
731 timestamp_t cutoff
= GENERATION_NUMBER_INFINITY
;
732 const struct commit_list
*p
;
734 for (p
= want
; p
; p
= p
->next
) {
735 timestamp_t generation
;
736 struct commit
*c
= p
->item
;
737 load_commit_graph_info(the_repository
, c
);
738 generation
= commit_graph_generation(c
);
739 if (generation
< cutoff
)
743 result
= contains_test(candidate
, want
, cache
, cutoff
);
744 if (result
!= CONTAINS_UNKNOWN
)
747 push_to_contains_stack(candidate
, &contains_stack
);
748 while (contains_stack
.nr
) {
749 struct contains_stack_entry
*entry
= &contains_stack
.contains_stack
[contains_stack
.nr
- 1];
750 struct commit
*commit
= entry
->commit
;
751 struct commit_list
*parents
= entry
->parents
;
754 *contains_cache_at(cache
, commit
) = CONTAINS_NO
;
758 * If we just popped the stack, parents->item has been marked,
759 * therefore contains_test will return a meaningful yes/no.
761 else switch (contains_test(parents
->item
, want
, cache
, cutoff
)) {
763 *contains_cache_at(cache
, commit
) = CONTAINS_YES
;
767 entry
->parents
= parents
->next
;
769 case CONTAINS_UNKNOWN
:
770 push_to_contains_stack(parents
->item
, &contains_stack
);
774 free(contains_stack
.contains_stack
);
775 return contains_test(candidate
, want
, cache
, cutoff
);
778 int commit_contains(struct ref_filter
*filter
, struct commit
*commit
,
779 struct commit_list
*list
, struct contains_cache
*cache
)
781 if (filter
->with_commit_tag_algo
)
782 return contains_tag_algo(commit
, list
, cache
) == CONTAINS_YES
;
783 return repo_is_descendant_of(the_repository
, commit
, list
);
786 int can_all_from_reach_with_flag(struct object_array
*from
,
787 unsigned int with_flag
,
788 unsigned int assign_flag
,
789 timestamp_t min_commit_date
,
790 timestamp_t min_generation
)
792 struct commit
**list
= NULL
;
797 ALLOC_ARRAY(list
, from
->nr
);
799 for (i
= 0; i
< from
->nr
; i
++) {
800 struct object
*from_one
= from
->objects
[i
].item
;
802 if (!from_one
|| from_one
->flags
& assign_flag
)
805 from_one
= deref_tag(the_repository
, from_one
,
807 if (!from_one
|| from_one
->type
!= OBJ_COMMIT
) {
809 * no way to tell if this is reachable by
810 * looking at the ancestry chain alone, so
811 * leave a note to ourselves not to worry about
812 * this object anymore.
814 from
->objects
[i
].item
->flags
|= assign_flag
;
818 list
[nr_commits
] = (struct commit
*)from_one
;
819 if (repo_parse_commit(the_repository
, list
[nr_commits
]) ||
820 commit_graph_generation(list
[nr_commits
]) < min_generation
) {
828 QSORT(list
, nr_commits
, compare_commits_by_gen
);
830 for (i
= 0; i
< nr_commits
; i
++) {
831 /* DFS from list[i] */
832 struct commit_list
*stack
= NULL
;
834 list
[i
]->object
.flags
|= assign_flag
;
835 commit_list_insert(list
[i
], &stack
);
838 struct commit_list
*parent
;
840 if (stack
->item
->object
.flags
& (with_flag
| RESULT
)) {
843 stack
->item
->object
.flags
|= RESULT
;
847 for (parent
= stack
->item
->parents
; parent
; parent
= parent
->next
) {
848 if (parent
->item
->object
.flags
& (with_flag
| RESULT
))
849 stack
->item
->object
.flags
|= RESULT
;
851 if (!(parent
->item
->object
.flags
& assign_flag
)) {
852 parent
->item
->object
.flags
|= assign_flag
;
854 if (repo_parse_commit(the_repository
, parent
->item
) ||
855 parent
->item
->date
< min_commit_date
||
856 commit_graph_generation(parent
->item
) < min_generation
)
859 commit_list_insert(parent
->item
, &stack
);
868 if (!(list
[i
]->object
.flags
& (with_flag
| RESULT
))) {
875 clear_commit_marks_many(nr_commits
, list
, RESULT
| assign_flag
);
878 for (i
= 0; i
< from
->nr
; i
++) {
879 struct object
*from_one
= from
->objects
[i
].item
;
882 from_one
->flags
&= ~assign_flag
;
888 int can_all_from_reach(struct commit_list
*from
, struct commit_list
*to
,
889 int cutoff_by_min_date
)
891 struct object_array from_objs
= OBJECT_ARRAY_INIT
;
892 struct commit_list
*from_iter
= from
, *to_iter
= to
;
894 timestamp_t min_commit_date
= cutoff_by_min_date
? from
->item
->date
: 0;
895 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
898 add_object_array(&from_iter
->item
->object
, NULL
, &from_objs
);
900 if (!repo_parse_commit(the_repository
, from_iter
->item
)) {
901 timestamp_t generation
;
902 if (from_iter
->item
->date
< min_commit_date
)
903 min_commit_date
= from_iter
->item
->date
;
905 generation
= commit_graph_generation(from_iter
->item
);
906 if (generation
< min_generation
)
907 min_generation
= generation
;
910 from_iter
= from_iter
->next
;
914 if (!repo_parse_commit(the_repository
, to_iter
->item
)) {
915 timestamp_t generation
;
916 if (to_iter
->item
->date
< min_commit_date
)
917 min_commit_date
= to_iter
->item
->date
;
919 generation
= commit_graph_generation(to_iter
->item
);
920 if (generation
< min_generation
)
921 min_generation
= generation
;
924 to_iter
->item
->object
.flags
|= PARENT2
;
926 to_iter
= to_iter
->next
;
929 result
= can_all_from_reach_with_flag(&from_objs
, PARENT2
, PARENT1
,
930 min_commit_date
, min_generation
);
933 clear_commit_marks(from
->item
, PARENT1
);
938 clear_commit_marks(to
->item
, PARENT2
);
942 object_array_clear(&from_objs
);
946 struct commit_list
*get_reachable_subset(struct commit
**from
, size_t nr_from
,
947 struct commit
**to
, size_t nr_to
,
948 unsigned int reachable_flag
)
950 struct commit
**item
;
951 struct commit
*current
;
952 struct commit_list
*found_commits
= NULL
;
953 struct commit
**to_last
= to
+ nr_to
;
954 struct commit
**from_last
= from
+ nr_from
;
955 timestamp_t min_generation
= GENERATION_NUMBER_INFINITY
;
958 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
960 for (item
= to
; item
< to_last
; item
++) {
961 timestamp_t generation
;
962 struct commit
*c
= *item
;
964 repo_parse_commit(the_repository
, c
);
965 generation
= commit_graph_generation(c
);
966 if (generation
< min_generation
)
967 min_generation
= generation
;
969 if (!(c
->object
.flags
& PARENT1
)) {
970 c
->object
.flags
|= PARENT1
;
975 for (item
= from
; item
< from_last
; item
++) {
976 struct commit
*c
= *item
;
977 if (!(c
->object
.flags
& PARENT2
)) {
978 c
->object
.flags
|= PARENT2
;
979 repo_parse_commit(the_repository
, c
);
981 prio_queue_put(&queue
, *item
);
985 while (num_to_find
&& (current
= prio_queue_get(&queue
)) != NULL
) {
986 struct commit_list
*parents
;
988 if (current
->object
.flags
& PARENT1
) {
989 current
->object
.flags
&= ~PARENT1
;
990 current
->object
.flags
|= reachable_flag
;
991 commit_list_insert(current
, &found_commits
);
995 for (parents
= current
->parents
; parents
; parents
= parents
->next
) {
996 struct commit
*p
= parents
->item
;
998 repo_parse_commit(the_repository
, p
);
1000 if (commit_graph_generation(p
) < min_generation
)
1003 if (p
->object
.flags
& PARENT2
)
1006 p
->object
.flags
|= PARENT2
;
1007 prio_queue_put(&queue
, p
);
1011 clear_prio_queue(&queue
);
1013 clear_commit_marks_many(nr_to
, to
, PARENT1
);
1014 clear_commit_marks_many(nr_from
, from
, PARENT2
);
1016 return found_commits
;
1019 define_commit_slab(bit_arrays
, struct bitmap
*);
1020 static struct bit_arrays bit_arrays
;
1022 static void insert_no_dup(struct prio_queue
*queue
, struct commit
*c
)
1024 if (c
->object
.flags
& PARENT2
)
1026 prio_queue_put(queue
, c
);
1027 c
->object
.flags
|= PARENT2
;
1030 static struct bitmap
*get_bit_array(struct commit
*c
, int width
)
1032 struct bitmap
**bitmap
= bit_arrays_at(&bit_arrays
, c
);
1034 *bitmap
= bitmap_word_alloc(width
);
1038 static void free_bit_array(struct commit
*c
)
1040 struct bitmap
**bitmap
= bit_arrays_at(&bit_arrays
, c
);
1043 bitmap_free(*bitmap
);
1047 void ahead_behind(struct repository
*r
,
1048 struct commit
**commits
, size_t commits_nr
,
1049 struct ahead_behind_count
*counts
, size_t counts_nr
)
1051 struct prio_queue queue
= { .compare
= compare_commits_by_gen_then_commit_date
};
1052 size_t width
= DIV_ROUND_UP(commits_nr
, BITS_IN_EWORD
);
1054 if (!commits_nr
|| !counts_nr
)
1057 for (size_t i
= 0; i
< counts_nr
; i
++) {
1058 counts
[i
].ahead
= 0;
1059 counts
[i
].behind
= 0;
1062 ensure_generations_valid(r
, commits
, commits_nr
);
1064 init_bit_arrays(&bit_arrays
);
1066 for (size_t i
= 0; i
< commits_nr
; i
++) {
1067 struct commit
*c
= commits
[i
];
1068 struct bitmap
*bitmap
= get_bit_array(c
, width
);
1070 bitmap_set(bitmap
, i
);
1071 insert_no_dup(&queue
, c
);
1074 while (queue_has_nonstale(&queue
)) {
1075 struct commit
*c
= prio_queue_get(&queue
);
1076 struct commit_list
*p
;
1077 struct bitmap
*bitmap_c
= get_bit_array(c
, width
);
1079 for (size_t i
= 0; i
< counts_nr
; i
++) {
1080 int reach_from_tip
= !!bitmap_get(bitmap_c
, counts
[i
].tip_index
);
1081 int reach_from_base
= !!bitmap_get(bitmap_c
, counts
[i
].base_index
);
1083 if (reach_from_tip
^ reach_from_base
) {
1084 if (reach_from_base
)
1091 for (p
= c
->parents
; p
; p
= p
->next
) {
1092 struct bitmap
*bitmap_p
;
1094 repo_parse_commit(r
, p
->item
);
1096 bitmap_p
= get_bit_array(p
->item
, width
);
1097 bitmap_or(bitmap_p
, bitmap_c
);
1100 * If this parent is reachable from every starting
1101 * commit, then none of its ancestors can contribute
1102 * to the ahead/behind count. Mark it as STALE, so
1103 * we can stop the walk when every commit in the
1106 if (bitmap_popcount(bitmap_p
) == commits_nr
)
1107 p
->item
->object
.flags
|= STALE
;
1109 insert_no_dup(&queue
, p
->item
);
1115 /* STALE is used here, PARENT2 is used by insert_no_dup(). */
1116 repo_clear_commit_marks(r
, PARENT2
| STALE
);
1117 while (prio_queue_peek(&queue
)) {
1118 struct commit
*c
= prio_queue_get(&queue
);
1121 clear_bit_arrays(&bit_arrays
);
1122 clear_prio_queue(&queue
);
1125 struct commit_and_index
{
1126 struct commit
*commit
;
1128 timestamp_t generation
;
1131 static int compare_commit_and_index_by_generation(const void *va
, const void *vb
)
1133 const struct commit_and_index
*a
= (const struct commit_and_index
*)va
;
1134 const struct commit_and_index
*b
= (const struct commit_and_index
*)vb
;
1136 if (a
->generation
> b
->generation
)
1138 if (a
->generation
< b
->generation
)
1143 void tips_reachable_from_bases(struct repository
*r
,
1144 struct commit_list
*bases
,
1145 struct commit
**tips
, size_t tips_nr
,
1148 struct commit_and_index
*commits
;
1149 size_t min_generation_index
= 0;
1150 timestamp_t min_generation
;
1151 struct commit_list
*stack
= NULL
;
1153 if (!bases
|| !tips
|| !tips_nr
)
1157 * Do a depth-first search starting at 'bases' to search for the
1158 * tips. Stop at the lowest (un-found) generation number. When
1159 * finding the lowest commit, increase the minimum generation
1160 * number to the next lowest (un-found) generation number.
1163 CALLOC_ARRAY(commits
, tips_nr
);
1165 for (size_t i
= 0; i
< tips_nr
; i
++) {
1166 commits
[i
].commit
= tips
[i
];
1167 commits
[i
].index
= i
;
1168 commits
[i
].generation
= commit_graph_generation(tips
[i
]);
1171 /* Sort with generation number ascending. */
1172 QSORT(commits
, tips_nr
, compare_commit_and_index_by_generation
);
1173 min_generation
= commits
[0].generation
;
1176 repo_parse_commit(r
, bases
->item
);
1177 commit_list_insert(bases
->item
, &stack
);
1178 bases
= bases
->next
;
1182 int explored_all_parents
= 1;
1183 struct commit_list
*p
;
1184 struct commit
*c
= stack
->item
;
1185 timestamp_t c_gen
= commit_graph_generation(c
);
1187 /* Does it match any of our tips? */
1188 for (size_t j
= min_generation_index
; j
< tips_nr
; j
++) {
1189 if (c_gen
< commits
[j
].generation
)
1192 if (commits
[j
].commit
== c
) {
1193 tips
[commits
[j
].index
]->object
.flags
|= mark
;
1195 if (j
== min_generation_index
) {
1196 unsigned int k
= j
+ 1;
1197 while (k
< tips_nr
&&
1198 (tips
[commits
[k
].index
]->object
.flags
& mark
))
1201 /* Terminate early if all found. */
1205 min_generation_index
= k
;
1206 min_generation
= commits
[k
].generation
;
1211 for (p
= c
->parents
; p
; p
= p
->next
) {
1212 repo_parse_commit(r
, p
->item
);
1214 /* Have we already explored this parent? */
1215 if (p
->item
->object
.flags
& SEEN
)
1218 /* Is it below the current minimum generation? */
1219 if (commit_graph_generation(p
->item
) < min_generation
)
1222 /* Ok, we will explore from here on. */
1223 p
->item
->object
.flags
|= SEEN
;
1224 explored_all_parents
= 0;
1225 commit_list_insert(p
->item
, &stack
);
1229 if (explored_all_parents
)
1235 repo_clear_commit_marks(r
, SEEN
);
1236 free_commit_list(stack
);
1240 * This slab initializes integers to zero, so use "-1" for "tip is best" and
1241 * "i + 1" for "bases[i] is best".
1243 define_commit_slab(best_branch_base
, int);
1244 static struct best_branch_base best_branch_base
;
1245 #define get_best(c) (*best_branch_base_at(&best_branch_base, (c)))
1246 #define set_best(c,v) (*best_branch_base_at(&best_branch_base, (c)) = (v))
1248 int get_branch_base_for_tip(struct repository
*r
,
1250 struct commit
**bases
,
1253 int best_index
= -1;
1254 struct commit
*branch_point
= NULL
;
1255 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
1256 int found_missing_gen
= 0;
1261 repo_parse_commit(r
, tip
);
1262 if (commit_graph_generation(tip
) == GENERATION_NUMBER_INFINITY
)
1263 found_missing_gen
= 1;
1265 /* Check for missing generation numbers. */
1266 for (size_t i
= 0; i
< bases_nr
; i
++) {
1267 struct commit
*c
= bases
[i
];
1268 repo_parse_commit(r
, c
);
1269 if (commit_graph_generation(c
) == GENERATION_NUMBER_INFINITY
)
1270 found_missing_gen
= 1;
1273 if (found_missing_gen
) {
1274 struct commit
**commits
;
1275 size_t commits_nr
= bases_nr
+ 1;
1277 CALLOC_ARRAY(commits
, commits_nr
);
1278 COPY_ARRAY(commits
, bases
, bases_nr
);
1279 commits
[bases_nr
] = tip
;
1280 ensure_generations_valid(r
, commits
, commits_nr
);
1284 /* Initialize queue and slab now that generations are guaranteed. */
1285 init_best_branch_base(&best_branch_base
);
1287 prio_queue_put(&queue
, tip
);
1289 for (size_t i
= 0; i
< bases_nr
; i
++) {
1290 struct commit
*c
= bases
[i
];
1291 int best
= get_best(c
);
1293 /* Has this already been marked as best by another commit? */
1296 /* We agree at this position. Stop now. */
1304 prio_queue_put(&queue
, c
);
1308 struct commit
*c
= prio_queue_get(&queue
);
1309 int best_for_c
= get_best(c
);
1310 int best_for_p
, positive
;
1311 struct commit
*parent
;
1313 /* Have we reached a known branch point? It's optimal. */
1314 if (c
== branch_point
)
1317 repo_parse_commit(r
, c
);
1321 parent
= c
->parents
->item
;
1322 repo_parse_commit(r
, parent
);
1323 best_for_p
= get_best(parent
);
1326 /* 'parent' is new, so pass along best_for_c. */
1327 set_best(parent
, best_for_c
);
1328 prio_queue_put(&queue
, parent
);
1332 if (best_for_p
> 0 && best_for_c
> 0) {
1333 /* Collision among bases. Minimize. */
1334 if (best_for_c
< best_for_p
)
1335 set_best(parent
, best_for_c
);
1340 * At this point, we have reached a commit that is reachable
1341 * from the tip, either from 'c' or from an earlier commit to
1342 * have 'parent' as its first parent.
1344 * Update 'best_index' to match the minimum of all base indices
1345 * to reach 'parent'.
1348 /* Exactly one is positive due to initial conditions. */
1349 positive
= (best_for_c
< 0) ? best_for_p
: best_for_c
;
1351 if (best_index
< 0 || positive
< best_index
)
1352 best_index
= positive
;
1354 /* No matter what, track that the parent is reachable from tip. */
1355 set_best(parent
, -1);
1356 branch_point
= parent
;
1360 clear_best_branch_base(&best_branch_base
);
1361 clear_prio_queue(&queue
);
1362 return best_index
> 0 ? best_index
- 1 : -1;