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 REACHABLE (1u<<15)
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 queue_has_nonstale(struct prio_queue
*queue
)
24 for (i
= 0; i
< queue
->nr
; i
++) {
25 struct commit
*commit
= queue
->array
[i
].data
;
26 if (!(commit
->object
.flags
& STALE
))
32 /* all input commits in one and twos[] must have been parsed! */
33 static struct commit_list
*paint_down_to_common(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
;
62 if (min_generation
&& commit
->generation
> last_gen
)
63 BUG("bad generation skip %8x > %8x at %s",
64 commit
->generation
, last_gen
,
65 oid_to_hex(&commit
->object
.oid
));
66 last_gen
= commit
->generation
;
68 if (commit
->generation
< min_generation
)
71 flags
= commit
->object
.flags
& (PARENT1
| PARENT2
| STALE
);
72 if (flags
== (PARENT1
| PARENT2
)) {
73 if (!(commit
->object
.flags
& RESULT
)) {
74 commit
->object
.flags
|= RESULT
;
75 commit_list_insert_by_date(commit
, &result
);
77 /* Mark parents of a found merge stale */
80 parents
= commit
->parents
;
82 struct commit
*p
= parents
->item
;
83 parents
= parents
->next
;
84 if ((p
->object
.flags
& flags
) == flags
)
88 p
->object
.flags
|= flags
;
89 prio_queue_put(&queue
, p
);
93 clear_prio_queue(&queue
);
97 static struct commit_list
*merge_bases_many(struct commit
*one
, int n
, struct commit
**twos
)
99 struct commit_list
*list
= NULL
;
100 struct commit_list
*result
= NULL
;
103 for (i
= 0; i
< n
; i
++) {
106 * We do not mark this even with RESULT so we do not
107 * have to clean it up.
109 return commit_list_insert(one
, &result
);
112 if (parse_commit(one
))
114 for (i
= 0; i
< n
; i
++) {
115 if (parse_commit(twos
[i
]))
119 list
= paint_down_to_common(one
, n
, twos
, 0);
122 struct commit
*commit
= pop_commit(&list
);
123 if (!(commit
->object
.flags
& STALE
))
124 commit_list_insert_by_date(commit
, &result
);
129 struct commit_list
*get_octopus_merge_bases(struct commit_list
*in
)
131 struct commit_list
*i
, *j
, *k
, *ret
= NULL
;
136 commit_list_insert(in
->item
, &ret
);
138 for (i
= in
->next
; i
; i
= i
->next
) {
139 struct commit_list
*new_commits
= NULL
, *end
= NULL
;
141 for (j
= ret
; j
; j
= j
->next
) {
142 struct commit_list
*bases
;
143 bases
= get_merge_bases(i
->item
, j
->item
);
148 for (k
= bases
; k
; k
= k
->next
)
156 static int remove_redundant(struct commit
**array
, int cnt
)
159 * Some commit in the array may be an ancestor of
160 * another commit. Move such commit to the end of
161 * the array, and return the number of commits that
162 * are independent from each other.
164 struct commit
**work
;
165 unsigned char *redundant
;
169 work
= xcalloc(cnt
, sizeof(*work
));
170 redundant
= xcalloc(cnt
, 1);
171 ALLOC_ARRAY(filled_index
, cnt
- 1);
173 for (i
= 0; i
< cnt
; i
++)
174 parse_commit(array
[i
]);
175 for (i
= 0; i
< cnt
; i
++) {
176 struct commit_list
*common
;
177 uint32_t min_generation
= array
[i
]->generation
;
181 for (j
= filled
= 0; j
< cnt
; j
++) {
182 if (i
== j
|| redundant
[j
])
184 filled_index
[filled
] = j
;
185 work
[filled
++] = array
[j
];
187 if (array
[j
]->generation
< min_generation
)
188 min_generation
= array
[j
]->generation
;
190 common
= paint_down_to_common(array
[i
], filled
, work
,
192 if (array
[i
]->object
.flags
& PARENT2
)
194 for (j
= 0; j
< filled
; j
++)
195 if (work
[j
]->object
.flags
& PARENT1
)
196 redundant
[filled_index
[j
]] = 1;
197 clear_commit_marks(array
[i
], all_flags
);
198 clear_commit_marks_many(filled
, work
, all_flags
);
199 free_commit_list(common
);
202 /* Now collect the result */
203 COPY_ARRAY(work
, array
, cnt
);
204 for (i
= filled
= 0; i
< cnt
; i
++)
206 array
[filled
++] = work
[i
];
207 for (j
= filled
, i
= 0; i
< cnt
; i
++)
209 array
[j
++] = work
[i
];
216 static struct commit_list
*get_merge_bases_many_0(struct commit
*one
,
218 struct commit
**twos
,
221 struct commit_list
*list
;
222 struct commit
**rslt
;
223 struct commit_list
*result
;
226 result
= merge_bases_many(one
, n
, twos
);
227 for (i
= 0; i
< n
; i
++) {
231 if (!result
|| !result
->next
) {
233 clear_commit_marks(one
, all_flags
);
234 clear_commit_marks_many(n
, twos
, all_flags
);
239 /* There are more than one */
240 cnt
= commit_list_count(result
);
241 rslt
= xcalloc(cnt
, sizeof(*rslt
));
242 for (list
= result
, i
= 0; list
; list
= list
->next
)
243 rslt
[i
++] = list
->item
;
244 free_commit_list(result
);
246 clear_commit_marks(one
, all_flags
);
247 clear_commit_marks_many(n
, twos
, all_flags
);
249 cnt
= remove_redundant(rslt
, cnt
);
251 for (i
= 0; i
< cnt
; i
++)
252 commit_list_insert_by_date(rslt
[i
], &result
);
257 struct commit_list
*get_merge_bases_many(struct commit
*one
,
259 struct commit
**twos
)
261 return get_merge_bases_many_0(one
, n
, twos
, 1);
264 struct commit_list
*get_merge_bases_many_dirty(struct commit
*one
,
266 struct commit
**twos
)
268 return get_merge_bases_many_0(one
, n
, twos
, 0);
271 struct commit_list
*get_merge_bases(struct commit
*one
, struct commit
*two
)
273 return get_merge_bases_many_0(one
, 1, &two
, 1);
277 * Is "commit" a descendant of one of the elements on the "with_commit" list?
279 int is_descendant_of(struct commit
*commit
, struct commit_list
*with_commit
)
284 if (generation_numbers_enabled(the_repository
)) {
285 struct commit_list
*from_list
= NULL
;
287 commit_list_insert(commit
, &from_list
);
288 result
= can_all_from_reach(from_list
, with_commit
, 0);
289 free_commit_list(from_list
);
292 while (with_commit
) {
293 struct commit
*other
;
295 other
= with_commit
->item
;
296 with_commit
= with_commit
->next
;
297 if (in_merge_bases(other
, commit
))
305 * Is "commit" an ancestor of one of the "references"?
307 int in_merge_bases_many(struct commit
*commit
, int nr_reference
, struct commit
**reference
)
309 struct commit_list
*bases
;
311 uint32_t min_generation
= GENERATION_NUMBER_INFINITY
;
313 if (parse_commit(commit
))
315 for (i
= 0; i
< nr_reference
; i
++) {
316 if (parse_commit(reference
[i
]))
318 if (reference
[i
]->generation
< min_generation
)
319 min_generation
= reference
[i
]->generation
;
322 if (commit
->generation
> min_generation
)
325 bases
= paint_down_to_common(commit
, nr_reference
, reference
, commit
->generation
);
326 if (commit
->object
.flags
& PARENT2
)
328 clear_commit_marks(commit
, all_flags
);
329 clear_commit_marks_many(nr_reference
, reference
, all_flags
);
330 free_commit_list(bases
);
335 * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
337 int in_merge_bases(struct commit
*commit
, struct commit
*reference
)
339 return in_merge_bases_many(commit
, 1, &reference
);
342 struct commit_list
*reduce_heads(struct commit_list
*heads
)
344 struct commit_list
*p
;
345 struct commit_list
*result
= NULL
, **tail
= &result
;
346 struct commit
**array
;
353 for (p
= heads
; p
; p
= p
->next
)
354 p
->item
->object
.flags
&= ~STALE
;
355 for (p
= heads
, num_head
= 0; p
; p
= p
->next
) {
356 if (p
->item
->object
.flags
& STALE
)
358 p
->item
->object
.flags
|= STALE
;
361 array
= xcalloc(num_head
, sizeof(*array
));
362 for (p
= heads
, i
= 0; p
; p
= p
->next
) {
363 if (p
->item
->object
.flags
& STALE
) {
364 array
[i
++] = p
->item
;
365 p
->item
->object
.flags
&= ~STALE
;
368 num_head
= remove_redundant(array
, num_head
);
369 for (i
= 0; i
< num_head
; i
++)
370 tail
= &commit_list_insert(array
[i
], tail
)->next
;
375 void reduce_heads_replace(struct commit_list
**heads
)
377 struct commit_list
*result
= reduce_heads(*heads
);
378 free_commit_list(*heads
);
382 int ref_newer(const struct object_id
*new_oid
, const struct object_id
*old_oid
)
385 struct commit
*old_commit
, *new_commit
;
386 struct commit_list
*old_commit_list
= NULL
;
389 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
390 * old_commit. Otherwise we require --force.
392 o
= deref_tag(the_repository
, parse_object(the_repository
, old_oid
),
394 if (!o
|| o
->type
!= OBJ_COMMIT
)
396 old_commit
= (struct commit
*) o
;
398 o
= deref_tag(the_repository
, parse_object(the_repository
, new_oid
),
400 if (!o
|| o
->type
!= OBJ_COMMIT
)
402 new_commit
= (struct commit
*) o
;
404 if (parse_commit(new_commit
) < 0)
407 commit_list_insert(old_commit
, &old_commit_list
);
408 return is_descendant_of(new_commit
, old_commit_list
);
412 * Mimicking the real stack, this stack lives on the heap, avoiding stack
415 * At each recursion step, the stack items points to the commits whose
416 * ancestors are to be inspected.
418 struct contains_stack
{
420 struct contains_stack_entry
{
421 struct commit
*commit
;
422 struct commit_list
*parents
;
426 static int in_commit_list(const struct commit_list
*want
, struct commit
*c
)
428 for (; want
; want
= want
->next
)
429 if (!oidcmp(&want
->item
->object
.oid
, &c
->object
.oid
))
435 * Test whether the candidate is contained in the list.
436 * Do not recurse to find out, though, but return -1 if inconclusive.
438 static enum contains_result
contains_test(struct commit
*candidate
,
439 const struct commit_list
*want
,
440 struct contains_cache
*cache
,
443 enum contains_result
*cached
= contains_cache_at(cache
, candidate
);
445 /* If we already have the answer cached, return that. */
450 if (in_commit_list(want
, candidate
)) {
451 *cached
= CONTAINS_YES
;
455 /* Otherwise, we don't know; prepare to recurse */
456 parse_commit_or_die(candidate
);
458 if (candidate
->generation
< cutoff
)
461 return CONTAINS_UNKNOWN
;
464 static void push_to_contains_stack(struct commit
*candidate
, struct contains_stack
*contains_stack
)
466 ALLOC_GROW(contains_stack
->contains_stack
, contains_stack
->nr
+ 1, contains_stack
->alloc
);
467 contains_stack
->contains_stack
[contains_stack
->nr
].commit
= candidate
;
468 contains_stack
->contains_stack
[contains_stack
->nr
++].parents
= candidate
->parents
;
471 static enum contains_result
contains_tag_algo(struct commit
*candidate
,
472 const struct commit_list
*want
,
473 struct contains_cache
*cache
)
475 struct contains_stack contains_stack
= { 0, 0, NULL
};
476 enum contains_result result
;
477 uint32_t cutoff
= GENERATION_NUMBER_INFINITY
;
478 const struct commit_list
*p
;
480 for (p
= want
; p
; p
= p
->next
) {
481 struct commit
*c
= p
->item
;
482 load_commit_graph_info(the_repository
, c
);
483 if (c
->generation
< cutoff
)
484 cutoff
= c
->generation
;
487 result
= contains_test(candidate
, want
, cache
, cutoff
);
488 if (result
!= CONTAINS_UNKNOWN
)
491 push_to_contains_stack(candidate
, &contains_stack
);
492 while (contains_stack
.nr
) {
493 struct contains_stack_entry
*entry
= &contains_stack
.contains_stack
[contains_stack
.nr
- 1];
494 struct commit
*commit
= entry
->commit
;
495 struct commit_list
*parents
= entry
->parents
;
498 *contains_cache_at(cache
, commit
) = CONTAINS_NO
;
502 * If we just popped the stack, parents->item has been marked,
503 * therefore contains_test will return a meaningful yes/no.
505 else switch (contains_test(parents
->item
, want
, cache
, cutoff
)) {
507 *contains_cache_at(cache
, commit
) = CONTAINS_YES
;
511 entry
->parents
= parents
->next
;
513 case CONTAINS_UNKNOWN
:
514 push_to_contains_stack(parents
->item
, &contains_stack
);
518 free(contains_stack
.contains_stack
);
519 return contains_test(candidate
, want
, cache
, cutoff
);
522 int commit_contains(struct ref_filter
*filter
, struct commit
*commit
,
523 struct commit_list
*list
, struct contains_cache
*cache
)
525 if (filter
->with_commit_tag_algo
)
526 return contains_tag_algo(commit
, list
, cache
) == CONTAINS_YES
;
527 return is_descendant_of(commit
, list
);
530 static int compare_commits_by_gen(const void *_a
, const void *_b
)
532 const struct commit
*a
= (const struct commit
*)_a
;
533 const struct commit
*b
= (const struct commit
*)_b
;
535 if (a
->generation
< b
->generation
)
537 if (a
->generation
> b
->generation
)
542 int can_all_from_reach_with_flag(struct object_array
*from
,
543 unsigned int with_flag
,
544 unsigned int assign_flag
,
545 time_t min_commit_date
,
546 uint32_t min_generation
)
548 struct commit
**list
= NULL
;
552 ALLOC_ARRAY(list
, from
->nr
);
553 for (i
= 0; i
< from
->nr
; i
++) {
554 list
[i
] = (struct commit
*)from
->objects
[i
].item
;
556 if (parse_commit(list
[i
]) ||
557 list
[i
]->generation
< min_generation
)
561 QSORT(list
, from
->nr
, compare_commits_by_gen
);
563 for (i
= 0; i
< from
->nr
; i
++) {
564 /* DFS from list[i] */
565 struct commit_list
*stack
= NULL
;
567 list
[i
]->object
.flags
|= assign_flag
;
568 commit_list_insert(list
[i
], &stack
);
571 struct commit_list
*parent
;
573 if (stack
->item
->object
.flags
& with_flag
) {
578 for (parent
= stack
->item
->parents
; parent
; parent
= parent
->next
) {
579 if (parent
->item
->object
.flags
& (with_flag
| RESULT
))
580 stack
->item
->object
.flags
|= RESULT
;
582 if (!(parent
->item
->object
.flags
& assign_flag
)) {
583 parent
->item
->object
.flags
|= assign_flag
;
585 if (parse_commit(parent
->item
) ||
586 parent
->item
->date
< min_commit_date
||
587 parent
->item
->generation
< min_generation
)
590 commit_list_insert(parent
->item
, &stack
);
599 if (!(list
[i
]->object
.flags
& (with_flag
| RESULT
))) {
606 for (i
= 0; i
< from
->nr
; i
++) {
607 clear_commit_marks(list
[i
], RESULT
);
608 clear_commit_marks(list
[i
], assign_flag
);
613 int can_all_from_reach(struct commit_list
*from
, struct commit_list
*to
,
614 int cutoff_by_min_date
)
616 struct object_array from_objs
= OBJECT_ARRAY_INIT
;
617 time_t min_commit_date
= cutoff_by_min_date
? from
->item
->date
: 0;
618 struct commit_list
*from_iter
= from
, *to_iter
= to
;
620 uint32_t min_generation
= GENERATION_NUMBER_INFINITY
;
623 add_object_array(&from_iter
->item
->object
, NULL
, &from_objs
);
625 if (!parse_commit(from_iter
->item
)) {
626 if (from_iter
->item
->date
< min_commit_date
)
627 min_commit_date
= from_iter
->item
->date
;
629 if (from_iter
->item
->generation
< min_generation
)
630 min_generation
= from_iter
->item
->generation
;
633 from_iter
= from_iter
->next
;
637 if (!parse_commit(to_iter
->item
)) {
638 if (to_iter
->item
->date
< min_commit_date
)
639 min_commit_date
= to_iter
->item
->date
;
641 if (to_iter
->item
->generation
< min_generation
)
642 min_generation
= to_iter
->item
->generation
;
645 to_iter
->item
->object
.flags
|= PARENT2
;
647 to_iter
= to_iter
->next
;
650 result
= can_all_from_reach_with_flag(&from_objs
, PARENT2
, PARENT1
,
651 min_commit_date
, min_generation
);
654 clear_commit_marks(from
->item
, PARENT1
);
659 clear_commit_marks(to
->item
, PARENT2
);
663 object_array_clear(&from_objs
);