3 #include "commit-graph.h"
5 #include "prio-queue.h"
7 #include "ref-filter.h"
10 #include "commit-reach.h"
12 /* Remember to update object flag allocation in object.h */
13 #define PARENT1 (1u<<16)
14 #define PARENT2 (1u<<17)
15 #define STALE (1u<<18)
16 #define RESULT (1u<<19)
18 static const unsigned all_flags
= (PARENT1
| PARENT2
| STALE
| RESULT
);
20 static int queue_has_nonstale(struct prio_queue
*queue
)
23 for (i
= 0; i
< queue
->nr
; i
++) {
24 struct commit
*commit
= queue
->array
[i
].data
;
25 if (!(commit
->object
.flags
& STALE
))
31 /* all input commits in one and twos[] must have been parsed! */
32 static struct commit_list
*paint_down_to_common(struct repository
*r
,
33 struct commit
*one
, int n
,
37 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
38 struct commit_list
*result
= NULL
;
40 uint32_t last_gen
= GENERATION_NUMBER_INFINITY
;
43 queue
.compare
= compare_commits_by_commit_date
;
45 one
->object
.flags
|= PARENT1
;
47 commit_list_append(one
, &result
);
50 prio_queue_put(&queue
, one
);
52 for (i
= 0; i
< n
; i
++) {
53 twos
[i
]->object
.flags
|= PARENT2
;
54 prio_queue_put(&queue
, twos
[i
]);
57 while (queue_has_nonstale(&queue
)) {
58 struct commit
*commit
= prio_queue_get(&queue
);
59 struct commit_list
*parents
;
61 uint32_t generation
= commit_graph_generation(commit
);
63 if (min_generation
&& generation
> last_gen
)
64 BUG("bad generation skip %8x > %8x at %s",
66 oid_to_hex(&commit
->object
.oid
));
67 last_gen
= generation
;
69 if (generation
< min_generation
)
72 flags
= commit
->object
.flags
& (PARENT1
| PARENT2
| STALE
);
73 if (flags
== (PARENT1
| PARENT2
)) {
74 if (!(commit
->object
.flags
& RESULT
)) {
75 commit
->object
.flags
|= RESULT
;
76 commit_list_insert_by_date(commit
, &result
);
78 /* Mark parents of a found merge stale */
81 parents
= commit
->parents
;
83 struct commit
*p
= parents
->item
;
84 parents
= parents
->next
;
85 if ((p
->object
.flags
& flags
) == flags
)
87 if (repo_parse_commit(r
, p
))
89 p
->object
.flags
|= flags
;
90 prio_queue_put(&queue
, p
);
94 clear_prio_queue(&queue
);
98 static struct commit_list
*merge_bases_many(struct repository
*r
,
99 struct commit
*one
, int n
,
100 struct commit
**twos
)
102 struct commit_list
*list
= NULL
;
103 struct commit_list
*result
= NULL
;
106 for (i
= 0; i
< n
; i
++) {
109 * We do not mark this even with RESULT so we do not
110 * have to clean it up.
112 return commit_list_insert(one
, &result
);
115 if (repo_parse_commit(r
, one
))
117 for (i
= 0; i
< n
; i
++) {
118 if (repo_parse_commit(r
, twos
[i
]))
122 list
= paint_down_to_common(r
, one
, n
, twos
, 0);
125 struct commit
*commit
= pop_commit(&list
);
126 if (!(commit
->object
.flags
& STALE
))
127 commit_list_insert_by_date(commit
, &result
);
132 struct commit_list
*get_octopus_merge_bases(struct commit_list
*in
)
134 struct commit_list
*i
, *j
, *k
, *ret
= NULL
;
139 commit_list_insert(in
->item
, &ret
);
141 for (i
= in
->next
; i
; i
= i
->next
) {
142 struct commit_list
*new_commits
= NULL
, *end
= NULL
;
144 for (j
= ret
; j
; j
= j
->next
) {
145 struct commit_list
*bases
;
146 bases
= get_merge_bases(i
->item
, j
->item
);
151 for (k
= bases
; k
; k
= k
->next
)
159 static int remove_redundant(struct repository
*r
, struct commit
**array
, int cnt
)
162 * Some commit in the array may be an ancestor of
163 * another commit. Move such commit to the end of
164 * the array, and return the number of commits that
165 * are independent from each other.
167 struct commit
**work
;
168 unsigned char *redundant
;
172 work
= xcalloc(cnt
, sizeof(*work
));
173 redundant
= xcalloc(cnt
, 1);
174 ALLOC_ARRAY(filled_index
, cnt
- 1);
176 for (i
= 0; i
< cnt
; i
++)
177 repo_parse_commit(r
, array
[i
]);
178 for (i
= 0; i
< cnt
; i
++) {
179 struct commit_list
*common
;
180 uint32_t min_generation
= commit_graph_generation(array
[i
]);
184 for (j
= filled
= 0; j
< cnt
; j
++) {
185 uint32_t curr_generation
;
186 if (i
== j
|| redundant
[j
])
188 filled_index
[filled
] = j
;
189 work
[filled
++] = array
[j
];
191 curr_generation
= commit_graph_generation(array
[j
]);
192 if (curr_generation
< min_generation
)
193 min_generation
= curr_generation
;
195 common
= paint_down_to_common(r
, array
[i
], filled
,
196 work
, min_generation
);
197 if (array
[i
]->object
.flags
& PARENT2
)
199 for (j
= 0; j
< filled
; j
++)
200 if (work
[j
]->object
.flags
& PARENT1
)
201 redundant
[filled_index
[j
]] = 1;
202 clear_commit_marks(array
[i
], all_flags
);
203 clear_commit_marks_many(filled
, work
, all_flags
);
204 free_commit_list(common
);
207 /* Now collect the result */
208 COPY_ARRAY(work
, array
, cnt
);
209 for (i
= filled
= 0; i
< cnt
; i
++)
211 array
[filled
++] = work
[i
];
212 for (j
= filled
, i
= 0; i
< cnt
; i
++)
214 array
[j
++] = work
[i
];
221 static struct commit_list
*get_merge_bases_many_0(struct repository
*r
,
224 struct commit
**twos
,
227 struct commit_list
*list
;
228 struct commit
**rslt
;
229 struct commit_list
*result
;
232 result
= merge_bases_many(r
, one
, n
, twos
);
233 for (i
= 0; i
< n
; i
++) {
237 if (!result
|| !result
->next
) {
239 clear_commit_marks(one
, all_flags
);
240 clear_commit_marks_many(n
, twos
, all_flags
);
245 /* There are more than one */
246 cnt
= commit_list_count(result
);
247 rslt
= xcalloc(cnt
, sizeof(*rslt
));
248 for (list
= result
, i
= 0; list
; list
= list
->next
)
249 rslt
[i
++] = list
->item
;
250 free_commit_list(result
);
252 clear_commit_marks(one
, all_flags
);
253 clear_commit_marks_many(n
, twos
, all_flags
);
255 cnt
= remove_redundant(r
, rslt
, cnt
);
257 for (i
= 0; i
< cnt
; i
++)
258 commit_list_insert_by_date(rslt
[i
], &result
);
263 struct commit_list
*repo_get_merge_bases_many(struct repository
*r
,
266 struct commit
**twos
)
268 return get_merge_bases_many_0(r
, one
, n
, twos
, 1);
271 struct commit_list
*repo_get_merge_bases_many_dirty(struct repository
*r
,
274 struct commit
**twos
)
276 return get_merge_bases_many_0(r
, one
, n
, twos
, 0);
279 struct commit_list
*repo_get_merge_bases(struct repository
*r
,
283 return get_merge_bases_many_0(r
, one
, 1, &two
, 1);
287 * Is "commit" a descendant of one of the elements on the "with_commit" list?
289 static int repo_is_descendant_of(struct repository
*r
,
290 struct commit
*commit
,
291 struct commit_list
*with_commit
)
296 if (generation_numbers_enabled(the_repository
)) {
297 struct commit_list
*from_list
= NULL
;
299 commit_list_insert(commit
, &from_list
);
300 result
= can_all_from_reach(from_list
, with_commit
, 0);
301 free_commit_list(from_list
);
304 while (with_commit
) {
305 struct commit
*other
;
307 other
= with_commit
->item
;
308 with_commit
= with_commit
->next
;
309 if (repo_in_merge_bases_many(r
, other
, 1, &commit
))
316 int is_descendant_of(struct commit
*commit
, struct commit_list
*with_commit
)
318 return repo_is_descendant_of(the_repository
, commit
, with_commit
);
322 * Is "commit" an ancestor of one of the "references"?
324 int repo_in_merge_bases_many(struct repository
*r
, struct commit
*commit
,
325 int nr_reference
, struct commit
**reference
)
327 struct commit_list
*bases
;
329 uint32_t generation
, min_generation
= GENERATION_NUMBER_INFINITY
;
331 if (repo_parse_commit(r
, commit
))
333 for (i
= 0; i
< nr_reference
; i
++) {
334 if (repo_parse_commit(r
, reference
[i
]))
337 generation
= commit_graph_generation(reference
[i
]);
338 if (generation
< min_generation
)
339 min_generation
= generation
;
342 generation
= commit_graph_generation(commit
);
343 if (generation
> min_generation
)
346 bases
= paint_down_to_common(r
, commit
,
347 nr_reference
, reference
,
349 if (commit
->object
.flags
& PARENT2
)
351 clear_commit_marks(commit
, all_flags
);
352 clear_commit_marks_many(nr_reference
, reference
, all_flags
);
353 free_commit_list(bases
);
358 * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
360 int repo_in_merge_bases(struct repository
*r
,
361 struct commit
*commit
,
362 struct commit
*reference
)
365 struct commit_list
*list
= NULL
;
366 struct commit_list
**next
= &list
;
368 next
= commit_list_append(commit
, next
);
369 res
= repo_is_descendant_of(r
, reference
, list
);
370 free_commit_list(list
);
375 struct commit_list
*reduce_heads(struct commit_list
*heads
)
377 struct commit_list
*p
;
378 struct commit_list
*result
= NULL
, **tail
= &result
;
379 struct commit
**array
;
386 for (p
= heads
; p
; p
= p
->next
)
387 p
->item
->object
.flags
&= ~STALE
;
388 for (p
= heads
, num_head
= 0; p
; p
= p
->next
) {
389 if (p
->item
->object
.flags
& STALE
)
391 p
->item
->object
.flags
|= STALE
;
394 array
= xcalloc(num_head
, sizeof(*array
));
395 for (p
= heads
, i
= 0; p
; p
= p
->next
) {
396 if (p
->item
->object
.flags
& STALE
) {
397 array
[i
++] = p
->item
;
398 p
->item
->object
.flags
&= ~STALE
;
401 num_head
= remove_redundant(the_repository
, array
, num_head
);
402 for (i
= 0; i
< num_head
; i
++)
403 tail
= &commit_list_insert(array
[i
], tail
)->next
;
408 void reduce_heads_replace(struct commit_list
**heads
)
410 struct commit_list
*result
= reduce_heads(*heads
);
411 free_commit_list(*heads
);
415 int ref_newer(const struct object_id
*new_oid
, const struct object_id
*old_oid
)
418 struct commit
*old_commit
, *new_commit
;
419 struct commit_list
*old_commit_list
= NULL
;
423 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
424 * old_commit. Otherwise we require --force.
426 o
= deref_tag(the_repository
, parse_object(the_repository
, old_oid
),
428 if (!o
|| o
->type
!= OBJ_COMMIT
)
430 old_commit
= (struct commit
*) o
;
432 o
= deref_tag(the_repository
, parse_object(the_repository
, new_oid
),
434 if (!o
|| o
->type
!= OBJ_COMMIT
)
436 new_commit
= (struct commit
*) o
;
438 if (parse_commit(new_commit
) < 0)
441 commit_list_insert(old_commit
, &old_commit_list
);
442 ret
= is_descendant_of(new_commit
, old_commit_list
);
443 free_commit_list(old_commit_list
);
448 * Mimicking the real stack, this stack lives on the heap, avoiding stack
451 * At each recursion step, the stack items points to the commits whose
452 * ancestors are to be inspected.
454 struct contains_stack
{
456 struct contains_stack_entry
{
457 struct commit
*commit
;
458 struct commit_list
*parents
;
462 static int in_commit_list(const struct commit_list
*want
, struct commit
*c
)
464 for (; want
; want
= want
->next
)
465 if (oideq(&want
->item
->object
.oid
, &c
->object
.oid
))
471 * Test whether the candidate is contained in the list.
472 * Do not recurse to find out, though, but return -1 if inconclusive.
474 static enum contains_result
contains_test(struct commit
*candidate
,
475 const struct commit_list
*want
,
476 struct contains_cache
*cache
,
479 enum contains_result
*cached
= contains_cache_at(cache
, candidate
);
481 /* If we already have the answer cached, return that. */
486 if (in_commit_list(want
, candidate
)) {
487 *cached
= CONTAINS_YES
;
491 /* Otherwise, we don't know; prepare to recurse */
492 parse_commit_or_die(candidate
);
494 if (commit_graph_generation(candidate
) < cutoff
)
497 return CONTAINS_UNKNOWN
;
500 static void push_to_contains_stack(struct commit
*candidate
, struct contains_stack
*contains_stack
)
502 ALLOC_GROW(contains_stack
->contains_stack
, contains_stack
->nr
+ 1, contains_stack
->alloc
);
503 contains_stack
->contains_stack
[contains_stack
->nr
].commit
= candidate
;
504 contains_stack
->contains_stack
[contains_stack
->nr
++].parents
= candidate
->parents
;
507 static enum contains_result
contains_tag_algo(struct commit
*candidate
,
508 const struct commit_list
*want
,
509 struct contains_cache
*cache
)
511 struct contains_stack contains_stack
= { 0, 0, NULL
};
512 enum contains_result result
;
513 uint32_t cutoff
= GENERATION_NUMBER_INFINITY
;
514 const struct commit_list
*p
;
516 for (p
= want
; p
; p
= p
->next
) {
518 struct commit
*c
= p
->item
;
519 load_commit_graph_info(the_repository
, c
);
520 generation
= commit_graph_generation(c
);
521 if (generation
< cutoff
)
525 result
= contains_test(candidate
, want
, cache
, cutoff
);
526 if (result
!= CONTAINS_UNKNOWN
)
529 push_to_contains_stack(candidate
, &contains_stack
);
530 while (contains_stack
.nr
) {
531 struct contains_stack_entry
*entry
= &contains_stack
.contains_stack
[contains_stack
.nr
- 1];
532 struct commit
*commit
= entry
->commit
;
533 struct commit_list
*parents
= entry
->parents
;
536 *contains_cache_at(cache
, commit
) = CONTAINS_NO
;
540 * If we just popped the stack, parents->item has been marked,
541 * therefore contains_test will return a meaningful yes/no.
543 else switch (contains_test(parents
->item
, want
, cache
, cutoff
)) {
545 *contains_cache_at(cache
, commit
) = CONTAINS_YES
;
549 entry
->parents
= parents
->next
;
551 case CONTAINS_UNKNOWN
:
552 push_to_contains_stack(parents
->item
, &contains_stack
);
556 free(contains_stack
.contains_stack
);
557 return contains_test(candidate
, want
, cache
, cutoff
);
560 int commit_contains(struct ref_filter
*filter
, struct commit
*commit
,
561 struct commit_list
*list
, struct contains_cache
*cache
)
563 if (filter
->with_commit_tag_algo
)
564 return contains_tag_algo(commit
, list
, cache
) == CONTAINS_YES
;
565 return is_descendant_of(commit
, list
);
568 static int compare_commits_by_gen(const void *_a
, const void *_b
)
570 const struct commit
*a
= *(const struct commit
* const *)_a
;
571 const struct commit
*b
= *(const struct commit
* const *)_b
;
573 uint32_t generation_a
= commit_graph_generation(a
);
574 uint32_t generation_b
= commit_graph_generation(b
);
576 if (generation_a
< generation_b
)
578 if (generation_a
> generation_b
)
583 int can_all_from_reach_with_flag(struct object_array
*from
,
584 unsigned int with_flag
,
585 unsigned int assign_flag
,
586 time_t min_commit_date
,
587 uint32_t min_generation
)
589 struct commit
**list
= NULL
;
594 ALLOC_ARRAY(list
, from
->nr
);
596 for (i
= 0; i
< from
->nr
; i
++) {
597 struct object
*from_one
= from
->objects
[i
].item
;
599 if (!from_one
|| from_one
->flags
& assign_flag
)
602 from_one
= deref_tag(the_repository
, from_one
,
604 if (!from_one
|| from_one
->type
!= OBJ_COMMIT
) {
606 * no way to tell if this is reachable by
607 * looking at the ancestry chain alone, so
608 * leave a note to ourselves not to worry about
609 * this object anymore.
611 from
->objects
[i
].item
->flags
|= assign_flag
;
615 list
[nr_commits
] = (struct commit
*)from_one
;
616 if (parse_commit(list
[nr_commits
]) ||
617 commit_graph_generation(list
[nr_commits
]) < min_generation
) {
625 QSORT(list
, nr_commits
, compare_commits_by_gen
);
627 for (i
= 0; i
< nr_commits
; i
++) {
628 /* DFS from list[i] */
629 struct commit_list
*stack
= NULL
;
631 list
[i
]->object
.flags
|= assign_flag
;
632 commit_list_insert(list
[i
], &stack
);
635 struct commit_list
*parent
;
637 if (stack
->item
->object
.flags
& (with_flag
| RESULT
)) {
640 stack
->item
->object
.flags
|= RESULT
;
644 for (parent
= stack
->item
->parents
; parent
; parent
= parent
->next
) {
645 if (parent
->item
->object
.flags
& (with_flag
| RESULT
))
646 stack
->item
->object
.flags
|= RESULT
;
648 if (!(parent
->item
->object
.flags
& assign_flag
)) {
649 parent
->item
->object
.flags
|= assign_flag
;
651 if (parse_commit(parent
->item
) ||
652 parent
->item
->date
< min_commit_date
||
653 commit_graph_generation(parent
->item
) < min_generation
)
656 commit_list_insert(parent
->item
, &stack
);
665 if (!(list
[i
]->object
.flags
& (with_flag
| RESULT
))) {
672 clear_commit_marks_many(nr_commits
, list
, RESULT
| assign_flag
);
675 for (i
= 0; i
< from
->nr
; i
++)
676 from
->objects
[i
].item
->flags
&= ~assign_flag
;
681 int can_all_from_reach(struct commit_list
*from
, struct commit_list
*to
,
682 int cutoff_by_min_date
)
684 struct object_array from_objs
= OBJECT_ARRAY_INIT
;
685 time_t min_commit_date
= cutoff_by_min_date
? from
->item
->date
: 0;
686 struct commit_list
*from_iter
= from
, *to_iter
= to
;
688 uint32_t min_generation
= GENERATION_NUMBER_INFINITY
;
691 add_object_array(&from_iter
->item
->object
, NULL
, &from_objs
);
693 if (!parse_commit(from_iter
->item
)) {
695 if (from_iter
->item
->date
< min_commit_date
)
696 min_commit_date
= from_iter
->item
->date
;
698 generation
= commit_graph_generation(from_iter
->item
);
699 if (generation
< min_generation
)
700 min_generation
= generation
;
703 from_iter
= from_iter
->next
;
707 if (!parse_commit(to_iter
->item
)) {
709 if (to_iter
->item
->date
< min_commit_date
)
710 min_commit_date
= to_iter
->item
->date
;
712 generation
= commit_graph_generation(to_iter
->item
);
713 if (generation
< min_generation
)
714 min_generation
= generation
;
717 to_iter
->item
->object
.flags
|= PARENT2
;
719 to_iter
= to_iter
->next
;
722 result
= can_all_from_reach_with_flag(&from_objs
, PARENT2
, PARENT1
,
723 min_commit_date
, min_generation
);
726 clear_commit_marks(from
->item
, PARENT1
);
731 clear_commit_marks(to
->item
, PARENT2
);
735 object_array_clear(&from_objs
);
739 struct commit_list
*get_reachable_subset(struct commit
**from
, int nr_from
,
740 struct commit
**to
, int nr_to
,
741 unsigned int reachable_flag
)
743 struct commit
**item
;
744 struct commit
*current
;
745 struct commit_list
*found_commits
= NULL
;
746 struct commit
**to_last
= to
+ nr_to
;
747 struct commit
**from_last
= from
+ nr_from
;
748 uint32_t min_generation
= GENERATION_NUMBER_INFINITY
;
751 struct prio_queue queue
= { compare_commits_by_gen_then_commit_date
};
753 for (item
= to
; item
< to_last
; item
++) {
755 struct commit
*c
= *item
;
758 generation
= commit_graph_generation(c
);
759 if (generation
< min_generation
)
760 min_generation
= generation
;
762 if (!(c
->object
.flags
& PARENT1
)) {
763 c
->object
.flags
|= PARENT1
;
768 for (item
= from
; item
< from_last
; item
++) {
769 struct commit
*c
= *item
;
770 if (!(c
->object
.flags
& PARENT2
)) {
771 c
->object
.flags
|= PARENT2
;
774 prio_queue_put(&queue
, *item
);
778 while (num_to_find
&& (current
= prio_queue_get(&queue
)) != NULL
) {
779 struct commit_list
*parents
;
781 if (current
->object
.flags
& PARENT1
) {
782 current
->object
.flags
&= ~PARENT1
;
783 current
->object
.flags
|= reachable_flag
;
784 commit_list_insert(current
, &found_commits
);
788 for (parents
= current
->parents
; parents
; parents
= parents
->next
) {
789 struct commit
*p
= parents
->item
;
793 if (commit_graph_generation(p
) < min_generation
)
796 if (p
->object
.flags
& PARENT2
)
799 p
->object
.flags
|= PARENT2
;
800 prio_queue_put(&queue
, p
);
804 clear_commit_marks_many(nr_to
, to
, PARENT1
);
805 clear_commit_marks_many(nr_from
, from
, PARENT2
);
807 return found_commits
;