Git fork
at reftables-rust 1363 lines 35 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "commit.h" 5#include "commit-graph.h" 6#include "decorate.h" 7#include "hex.h" 8#include "prio-queue.h" 9#include "ref-filter.h" 10#include "revision.h" 11#include "tag.h" 12#include "commit-reach.h" 13#include "ewah/ewok.h" 14 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) 20 21static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT); 22 23static int compare_commits_by_gen(const void *_a, const void *_b) 24{ 25 const struct commit *a = *(const struct commit * const *)_a; 26 const struct commit *b = *(const struct commit * const *)_b; 27 28 timestamp_t generation_a = commit_graph_generation(a); 29 timestamp_t generation_b = commit_graph_generation(b); 30 31 if (generation_a < generation_b) 32 return -1; 33 if (generation_a > generation_b) 34 return 1; 35 if (a->date < b->date) 36 return -1; 37 if (a->date > b->date) 38 return 1; 39 return 0; 40} 41 42static int queue_has_nonstale(struct prio_queue *queue) 43{ 44 for (size_t i = 0; i < queue->nr; i++) { 45 struct commit *commit = queue->array[i].data; 46 if (!(commit->object.flags & STALE)) 47 return 1; 48 } 49 return 0; 50} 51 52/* all input commits in one and twos[] must have been parsed! */ 53static int paint_down_to_common(struct repository *r, 54 struct commit *one, int n, 55 struct commit **twos, 56 timestamp_t min_generation, 57 int ignore_missing_commits, 58 struct commit_list **result) 59{ 60 struct prio_queue queue = { compare_commits_by_gen_then_commit_date }; 61 int i; 62 timestamp_t last_gen = GENERATION_NUMBER_INFINITY; 63 64 if (!min_generation && !corrected_commit_dates_enabled(r)) 65 queue.compare = compare_commits_by_commit_date; 66 67 one->object.flags |= PARENT1; 68 if (!n) { 69 commit_list_append(one, result); 70 return 0; 71 } 72 prio_queue_put(&queue, one); 73 74 for (i = 0; i < n; i++) { 75 twos[i]->object.flags |= PARENT2; 76 prio_queue_put(&queue, twos[i]); 77 } 78 79 while (queue_has_nonstale(&queue)) { 80 struct commit *commit = prio_queue_get(&queue); 81 struct commit_list *parents; 82 int flags; 83 timestamp_t generation = commit_graph_generation(commit); 84 85 if (min_generation && generation > last_gen) 86 BUG("bad generation skip %"PRItime" > %"PRItime" at %s", 87 generation, last_gen, 88 oid_to_hex(&commit->object.oid)); 89 last_gen = generation; 90 91 if (generation < min_generation) 92 break; 93 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); 99 } 100 /* Mark parents of a found merge stale */ 101 flags |= STALE; 102 } 103 parents = commit->parents; 104 while (parents) { 105 struct commit *p = parents->item; 106 parents = parents->next; 107 if ((p->object.flags & flags) == flags) 108 continue; 109 if (repo_parse_commit(r, p)) { 110 clear_prio_queue(&queue); 111 free_commit_list(*result); 112 *result = NULL; 113 /* 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()`. 119 */ 120 if (ignore_missing_commits) 121 return 0; 122 return error(_("could not parse commit %s"), 123 oid_to_hex(&p->object.oid)); 124 } 125 p->object.flags |= flags; 126 prio_queue_put(&queue, p); 127 } 128 } 129 130 clear_prio_queue(&queue); 131 return 0; 132} 133 134static int merge_bases_many(struct repository *r, 135 struct commit *one, int n, 136 struct commit **twos, 137 struct commit_list **result) 138{ 139 struct commit_list *list = NULL; 140 int i; 141 142 for (i = 0; i < n; i++) { 143 if (one == twos[i]) { 144 /* 145 * We do not mark this even with RESULT so we do not 146 * have to clean it up. 147 */ 148 *result = commit_list_insert(one, result); 149 return 0; 150 } 151 } 152 153 if (!one) 154 return 0; 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++) { 159 if (!twos[i]) 160 return 0; 161 if (repo_parse_commit(r, twos[i])) 162 return error(_("could not parse commit %s"), 163 oid_to_hex(&twos[i]->object.oid)); 164 } 165 166 if (paint_down_to_common(r, one, n, twos, 0, 0, &list)) { 167 free_commit_list(list); 168 return -1; 169 } 170 171 while (list) { 172 struct commit *commit = pop_commit(&list); 173 if (!(commit->object.flags & STALE)) 174 commit_list_insert_by_date(commit, result); 175 } 176 return 0; 177} 178 179int get_octopus_merge_bases(struct commit_list *in, struct commit_list **result) 180{ 181 struct commit_list *i, *j, *k; 182 183 if (!in) 184 return 0; 185 186 commit_list_insert(in->item, result); 187 188 for (i = in->next; i; i = i->next) { 189 struct commit_list *new_commits = NULL, *end = NULL; 190 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); 197 *result = NULL; 198 return -1; 199 } 200 if (!new_commits) 201 new_commits = bases; 202 else 203 end->next = bases; 204 for (k = bases; k; k = k->next) 205 end = k; 206 } 207 free_commit_list(*result); 208 *result = new_commits; 209 } 210 return 0; 211} 212 213static int remove_redundant_no_gen(struct repository *r, 214 struct commit **array, 215 size_t cnt, size_t *dedup_cnt) 216{ 217 struct commit **work; 218 unsigned char *redundant; 219 size_t *filled_index; 220 size_t i, j, filled; 221 222 CALLOC_ARRAY(work, cnt); 223 redundant = xcalloc(cnt, 1); 224 ALLOC_ARRAY(filled_index, cnt - 1); 225 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]); 231 232 if (redundant[i]) 233 continue; 234 for (j = filled = 0; j < cnt; j++) { 235 timestamp_t curr_generation; 236 if (i == j || redundant[j]) 237 continue; 238 filled_index[filled] = j; 239 work[filled++] = array[j]; 240 241 curr_generation = commit_graph_generation(array[j]); 242 if (curr_generation < min_generation) 243 min_generation = curr_generation; 244 } 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); 250 free(work); 251 free(redundant); 252 free(filled_index); 253 return -1; 254 } 255 if (array[i]->object.flags & PARENT2) 256 redundant[i] = 1; 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); 263 } 264 265 /* Now collect the result */ 266 COPY_ARRAY(work, array, cnt); 267 for (i = filled = 0; i < cnt; i++) 268 if (!redundant[i]) 269 array[filled++] = work[i]; 270 *dedup_cnt = filled; 271 free(work); 272 free(redundant); 273 free(filled_index); 274 return 0; 275} 276 277static int remove_redundant_with_gen(struct repository *r, 278 struct commit **array, size_t cnt, 279 size_t *dedup_cnt) 280{ 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; 286 287 /* 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. 293 */ 294 DUP_ARRAY(sorted, array, cnt); 295 QSORT(sorted, cnt, compare_commits_by_gen); 296 min_generation = commit_graph_generation(sorted[0]); 297 298 ALLOC_ARRAY(walk_start, walk_start_alloc); 299 300 /* Mark all parents of the input as STALE */ 301 for (i = 0; i < cnt; i++) { 302 struct commit_list *parents; 303 304 repo_parse_commit(r, array[i]); 305 array[i]->object.flags |= RESULT; 306 parents = array[i]->parents; 307 308 while (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; 314 } 315 parents = parents->next; 316 } 317 } 318 319 QSORT(walk_start, walk_start_nr, compare_commits_by_gen); 320 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; 324 325 /* 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 329 * as before. 330 */ 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; 334 335 commit_list_insert(walk_start[i - 1], &stack); 336 walk_start[i - 1]->object.flags |= STALE; 337 338 while (stack) { 339 struct commit_list *parents; 340 struct commit *c = stack->item; 341 342 repo_parse_commit(r, c); 343 344 if (c->object.flags & RESULT) { 345 c->object.flags &= ~RESULT; 346 if (--count_still_independent <= 1) 347 break; 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)) 351 min_gen_pos++; 352 min_generation = commit_graph_generation(sorted[min_gen_pos]); 353 } 354 } 355 356 if (commit_graph_generation(c) < min_generation) { 357 pop_commit(&stack); 358 continue; 359 } 360 361 parents = c->parents; 362 while (parents) { 363 if (!(parents->item->object.flags & STALE)) { 364 parents->item->object.flags |= STALE; 365 commit_list_insert(parents->item, &stack); 366 break; 367 } 368 parents = parents->next; 369 } 370 371 /* pop if all parents have been visited already */ 372 if (!parents) 373 pop_commit(&stack); 374 } 375 free_commit_list(stack); 376 } 377 free(sorted); 378 379 /* clear result */ 380 for (i = 0; i < cnt; i++) 381 array[i]->object.flags &= ~RESULT; 382 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]; 387 } 388 389 /* clear marks */ 390 clear_commit_marks_many(walk_start_nr, walk_start, STALE); 391 free(walk_start); 392 393 *dedup_cnt = count_non_stale; 394 return 0; 395} 396 397static int remove_redundant(struct repository *r, struct commit **array, 398 size_t cnt, size_t *dedup_cnt) 399{ 400 /* 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 405 * that number. 406 */ 407 if (generation_numbers_enabled(r)) { 408 /* 409 * If we have a single commit with finite generation 410 * number, then the _with_gen algorithm is preferred. 411 */ 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); 415 } 416 } 417 418 return remove_redundant_no_gen(r, array, cnt, dedup_cnt); 419} 420 421static int get_merge_bases_many_0(struct repository *r, 422 struct commit *one, 423 size_t n, 424 struct commit **twos, 425 int cleanup, 426 struct commit_list **result) 427{ 428 struct commit_list *list; 429 struct commit **rslt; 430 size_t cnt, i; 431 int ret; 432 433 if (merge_bases_many(r, one, n, twos, result) < 0) 434 return -1; 435 for (i = 0; i < n; i++) { 436 if (one == twos[i]) 437 return 0; 438 } 439 if (!*result || !(*result)->next) { 440 if (cleanup) { 441 clear_commit_marks(one, all_flags); 442 clear_commit_marks_many(n, twos, all_flags); 443 } 444 return 0; 445 } 446 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); 453 *result = NULL; 454 455 clear_commit_marks(one, all_flags); 456 clear_commit_marks_many(n, twos, all_flags); 457 458 ret = remove_redundant(r, rslt, cnt, &cnt); 459 if (ret < 0) { 460 free(rslt); 461 return -1; 462 } 463 for (i = 0; i < cnt; i++) 464 commit_list_insert_by_date(rslt[i], result); 465 free(rslt); 466 return 0; 467} 468 469int repo_get_merge_bases_many(struct repository *r, 470 struct commit *one, 471 size_t n, 472 struct commit **twos, 473 struct commit_list **result) 474{ 475 return get_merge_bases_many_0(r, one, n, twos, 1, result); 476} 477 478int repo_get_merge_bases_many_dirty(struct repository *r, 479 struct commit *one, 480 size_t n, 481 struct commit **twos, 482 struct commit_list **result) 483{ 484 return get_merge_bases_many_0(r, one, n, twos, 0, result); 485} 486 487int repo_get_merge_bases(struct repository *r, 488 struct commit *one, 489 struct commit *two, 490 struct commit_list **result) 491{ 492 return get_merge_bases_many_0(r, one, 1, &two, 1, result); 493} 494 495/* 496 * Is "commit" a descendant of one of the elements on the "with_commit" list? 497 */ 498int repo_is_descendant_of(struct repository *r, 499 struct commit *commit, 500 struct commit_list *with_commit) 501{ 502 if (!with_commit) 503 return 1; 504 505 if (generation_numbers_enabled(r)) { 506 struct commit_list *from_list = NULL; 507 int result; 508 commit_list_insert(commit, &from_list); 509 result = can_all_from_reach(from_list, with_commit, 0); 510 free_commit_list(from_list); 511 return result; 512 } else { 513 while (with_commit) { 514 struct commit *other; 515 int ret; 516 517 other = with_commit->item; 518 with_commit = with_commit->next; 519 ret = repo_in_merge_bases_many(r, other, 1, &commit, 0); 520 if (ret) 521 return ret; 522 } 523 return 0; 524 } 525} 526 527/* 528 * Is "commit" an ancestor of one of the "references"? 529 */ 530int repo_in_merge_bases_many(struct repository *r, struct commit *commit, 531 int nr_reference, struct commit **reference, 532 int ignore_missing_commits) 533{ 534 struct commit_list *bases = NULL; 535 int ret = 0, i; 536 timestamp_t generation, max_generation = GENERATION_NUMBER_ZERO; 537 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; 543 544 generation = commit_graph_generation(reference[i]); 545 if (generation > max_generation) 546 max_generation = generation; 547 } 548 549 generation = commit_graph_generation(commit); 550 if (generation > max_generation) 551 return ret; 552 553 if (paint_down_to_common(r, commit, 554 nr_reference, reference, 555 generation, ignore_missing_commits, &bases)) 556 ret = -1; 557 else if (commit->object.flags & PARENT2) 558 ret = 1; 559 clear_commit_marks(commit, all_flags); 560 clear_commit_marks_many(nr_reference, reference, all_flags); 561 free_commit_list(bases); 562 return ret; 563} 564 565/* 566 * Is "commit" an ancestor of (i.e. reachable from) the "reference"? 567 */ 568int repo_in_merge_bases(struct repository *r, 569 struct commit *commit, 570 struct commit *reference) 571{ 572 int res; 573 struct commit_list *list = NULL; 574 struct commit_list **next = &list; 575 576 next = commit_list_append(commit, next); 577 res = repo_is_descendant_of(r, reference, list); 578 free_commit_list(list); 579 580 return res; 581} 582 583struct commit_list *reduce_heads(struct commit_list *heads) 584{ 585 struct commit_list *p; 586 struct commit_list *result = NULL, **tail = &result; 587 struct commit **array; 588 size_t num_head, i; 589 int ret; 590 591 if (!heads) 592 return NULL; 593 594 /* Uniquify */ 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) 599 continue; 600 p->item->object.flags |= STALE; 601 num_head++; 602 } 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; 608 } 609 } 610 611 ret = remove_redundant(the_repository, array, num_head, &num_head); 612 if (ret < 0) { 613 free(array); 614 return NULL; 615 } 616 617 for (i = 0; i < num_head; i++) 618 tail = &commit_list_insert(array[i], tail)->next; 619 free(array); 620 return result; 621} 622 623void reduce_heads_replace(struct commit_list **heads) 624{ 625 struct commit_list *result = reduce_heads(*heads); 626 free_commit_list(*heads); 627 *heads = result; 628} 629 630int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid) 631{ 632 struct object *o; 633 struct commit *old_commit, *new_commit; 634 struct commit_list *old_commit_list = NULL; 635 int ret; 636 637 /* 638 * Both new_commit and old_commit must be commit-ish and new_commit is descendant of 639 * old_commit. Otherwise we require --force. 640 */ 641 o = deref_tag(the_repository, parse_object(the_repository, old_oid), 642 NULL, 0); 643 if (!o || o->type != OBJ_COMMIT) 644 return 0; 645 old_commit = (struct commit *) o; 646 647 o = deref_tag(the_repository, parse_object(the_repository, new_oid), 648 NULL, 0); 649 if (!o || o->type != OBJ_COMMIT) 650 return 0; 651 new_commit = (struct commit *) o; 652 653 if (repo_parse_commit(the_repository, new_commit) < 0) 654 return 0; 655 656 commit_list_insert(old_commit, &old_commit_list); 657 ret = repo_is_descendant_of(the_repository, 658 new_commit, old_commit_list); 659 if (ret < 0) 660 exit(128); 661 free_commit_list(old_commit_list); 662 return ret; 663} 664 665/* 666 * Mimicking the real stack, this stack lives on the heap, avoiding stack 667 * overflows. 668 * 669 * At each recursion step, the stack items points to the commits whose 670 * ancestors are to be inspected. 671 */ 672struct contains_stack { 673 int nr, alloc; 674 struct contains_stack_entry { 675 struct commit *commit; 676 struct commit_list *parents; 677 } *contains_stack; 678}; 679 680static int in_commit_list(const struct commit_list *want, struct commit *c) 681{ 682 for (; want; want = want->next) 683 if (oideq(&want->item->object.oid, &c->object.oid)) 684 return 1; 685 return 0; 686} 687 688/* 689 * Test whether the candidate is contained in the list. 690 * Do not recurse to find out, though, but return -1 if inconclusive. 691 */ 692static enum contains_result contains_test(struct commit *candidate, 693 const struct commit_list *want, 694 struct contains_cache *cache, 695 timestamp_t cutoff) 696{ 697 enum contains_result *cached = contains_cache_at(cache, candidate); 698 699 /* If we already have the answer cached, return that. */ 700 if (*cached) 701 return *cached; 702 703 /* or are we it? */ 704 if (in_commit_list(want, candidate)) { 705 *cached = CONTAINS_YES; 706 return CONTAINS_YES; 707 } 708 709 /* Otherwise, we don't know; prepare to recurse */ 710 parse_commit_or_die(candidate); 711 712 if (commit_graph_generation(candidate) < cutoff) 713 return CONTAINS_NO; 714 715 return CONTAINS_UNKNOWN; 716} 717 718static void push_to_contains_stack(struct commit *candidate, struct contains_stack *contains_stack) 719{ 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; 723} 724 725static enum contains_result contains_tag_algo(struct commit *candidate, 726 const struct commit_list *want, 727 struct contains_cache *cache) 728{ 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; 733 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) 740 cutoff = generation; 741 } 742 743 result = contains_test(candidate, want, cache, cutoff); 744 if (result != CONTAINS_UNKNOWN) 745 return result; 746 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; 752 753 if (!parents) { 754 *contains_cache_at(cache, commit) = CONTAINS_NO; 755 contains_stack.nr--; 756 } 757 /* 758 * If we just popped the stack, parents->item has been marked, 759 * therefore contains_test will return a meaningful yes/no. 760 */ 761 else switch (contains_test(parents->item, want, cache, cutoff)) { 762 case CONTAINS_YES: 763 *contains_cache_at(cache, commit) = CONTAINS_YES; 764 contains_stack.nr--; 765 break; 766 case CONTAINS_NO: 767 entry->parents = parents->next; 768 break; 769 case CONTAINS_UNKNOWN: 770 push_to_contains_stack(parents->item, &contains_stack); 771 break; 772 } 773 } 774 free(contains_stack.contains_stack); 775 return contains_test(candidate, want, cache, cutoff); 776} 777 778int commit_contains(struct ref_filter *filter, struct commit *commit, 779 struct commit_list *list, struct contains_cache *cache) 780{ 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); 784} 785 786int 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) 791{ 792 struct commit **list = NULL; 793 size_t i; 794 size_t nr_commits; 795 int result = 1; 796 797 ALLOC_ARRAY(list, from->nr); 798 nr_commits = 0; 799 for (i = 0; i < from->nr; i++) { 800 struct object *from_one = from->objects[i].item; 801 802 if (!from_one || from_one->flags & assign_flag) 803 continue; 804 805 from_one = deref_tag(the_repository, from_one, 806 "a from object", 0); 807 if (!from_one || from_one->type != OBJ_COMMIT) { 808 /* 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. 813 */ 814 from->objects[i].item->flags |= assign_flag; 815 continue; 816 } 817 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) { 821 result = 0; 822 goto cleanup; 823 } 824 825 nr_commits++; 826 } 827 828 QSORT(list, nr_commits, compare_commits_by_gen); 829 830 for (i = 0; i < nr_commits; i++) { 831 /* DFS from list[i] */ 832 struct commit_list *stack = NULL; 833 834 list[i]->object.flags |= assign_flag; 835 commit_list_insert(list[i], &stack); 836 837 while (stack) { 838 struct commit_list *parent; 839 840 if (stack->item->object.flags & (with_flag | RESULT)) { 841 pop_commit(&stack); 842 if (stack) 843 stack->item->object.flags |= RESULT; 844 continue; 845 } 846 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; 850 851 if (!(parent->item->object.flags & assign_flag)) { 852 parent->item->object.flags |= assign_flag; 853 854 if (repo_parse_commit(the_repository, parent->item) || 855 parent->item->date < min_commit_date || 856 commit_graph_generation(parent->item) < min_generation) 857 continue; 858 859 commit_list_insert(parent->item, &stack); 860 break; 861 } 862 } 863 864 if (!parent) 865 pop_commit(&stack); 866 } 867 868 if (!(list[i]->object.flags & (with_flag | RESULT))) { 869 result = 0; 870 goto cleanup; 871 } 872 } 873 874cleanup: 875 clear_commit_marks_many(nr_commits, list, RESULT | assign_flag); 876 free(list); 877 878 for (i = 0; i < from->nr; i++) { 879 struct object *from_one = from->objects[i].item; 880 881 if (from_one) 882 from_one->flags &= ~assign_flag; 883 } 884 885 return result; 886} 887 888int can_all_from_reach(struct commit_list *from, struct commit_list *to, 889 int cutoff_by_min_date) 890{ 891 struct object_array from_objs = OBJECT_ARRAY_INIT; 892 struct commit_list *from_iter = from, *to_iter = to; 893 int result; 894 timestamp_t min_commit_date = cutoff_by_min_date ? from->item->date : 0; 895 timestamp_t min_generation = GENERATION_NUMBER_INFINITY; 896 897 while (from_iter) { 898 add_object_array(&from_iter->item->object, NULL, &from_objs); 899 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; 904 905 generation = commit_graph_generation(from_iter->item); 906 if (generation < min_generation) 907 min_generation = generation; 908 } 909 910 from_iter = from_iter->next; 911 } 912 913 while (to_iter) { 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; 918 919 generation = commit_graph_generation(to_iter->item); 920 if (generation < min_generation) 921 min_generation = generation; 922 } 923 924 to_iter->item->object.flags |= PARENT2; 925 926 to_iter = to_iter->next; 927 } 928 929 result = can_all_from_reach_with_flag(&from_objs, PARENT2, PARENT1, 930 min_commit_date, min_generation); 931 932 while (from) { 933 clear_commit_marks(from->item, PARENT1); 934 from = from->next; 935 } 936 937 while (to) { 938 clear_commit_marks(to->item, PARENT2); 939 to = to->next; 940 } 941 942 object_array_clear(&from_objs); 943 return result; 944} 945 946struct 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) 949{ 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; 956 int num_to_find = 0; 957 958 struct prio_queue queue = { compare_commits_by_gen_then_commit_date }; 959 960 for (item = to; item < to_last; item++) { 961 timestamp_t generation; 962 struct commit *c = *item; 963 964 repo_parse_commit(the_repository, c); 965 generation = commit_graph_generation(c); 966 if (generation < min_generation) 967 min_generation = generation; 968 969 if (!(c->object.flags & PARENT1)) { 970 c->object.flags |= PARENT1; 971 num_to_find++; 972 } 973 } 974 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); 980 981 prio_queue_put(&queue, *item); 982 } 983 } 984 985 while (num_to_find && (current = prio_queue_get(&queue)) != NULL) { 986 struct commit_list *parents; 987 988 if (current->object.flags & PARENT1) { 989 current->object.flags &= ~PARENT1; 990 current->object.flags |= reachable_flag; 991 commit_list_insert(current, &found_commits); 992 num_to_find--; 993 } 994 995 for (parents = current->parents; parents; parents = parents->next) { 996 struct commit *p = parents->item; 997 998 repo_parse_commit(the_repository, p); 999 1000 if (commit_graph_generation(p) < min_generation) 1001 continue; 1002 1003 if (p->object.flags & PARENT2) 1004 continue; 1005 1006 p->object.flags |= PARENT2; 1007 prio_queue_put(&queue, p); 1008 } 1009 } 1010 1011 clear_prio_queue(&queue); 1012 1013 clear_commit_marks_many(nr_to, to, PARENT1); 1014 clear_commit_marks_many(nr_from, from, PARENT2); 1015 1016 return found_commits; 1017} 1018 1019define_commit_slab(bit_arrays, struct bitmap *); 1020static struct bit_arrays bit_arrays; 1021 1022static void insert_no_dup(struct prio_queue *queue, struct commit *c) 1023{ 1024 if (c->object.flags & PARENT2) 1025 return; 1026 prio_queue_put(queue, c); 1027 c->object.flags |= PARENT2; 1028} 1029 1030static struct bitmap *get_bit_array(struct commit *c, int width) 1031{ 1032 struct bitmap **bitmap = bit_arrays_at(&bit_arrays, c); 1033 if (!*bitmap) 1034 *bitmap = bitmap_word_alloc(width); 1035 return *bitmap; 1036} 1037 1038static void free_bit_array(struct commit *c) 1039{ 1040 struct bitmap **bitmap = bit_arrays_at(&bit_arrays, c); 1041 if (!*bitmap) 1042 return; 1043 bitmap_free(*bitmap); 1044 *bitmap = NULL; 1045} 1046 1047void ahead_behind(struct repository *r, 1048 struct commit **commits, size_t commits_nr, 1049 struct ahead_behind_count *counts, size_t counts_nr) 1050{ 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); 1053 1054 if (!commits_nr || !counts_nr) 1055 return; 1056 1057 for (size_t i = 0; i < counts_nr; i++) { 1058 counts[i].ahead = 0; 1059 counts[i].behind = 0; 1060 } 1061 1062 ensure_generations_valid(r, commits, commits_nr); 1063 1064 init_bit_arrays(&bit_arrays); 1065 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); 1069 1070 bitmap_set(bitmap, i); 1071 insert_no_dup(&queue, c); 1072 } 1073 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); 1078 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); 1082 1083 if (reach_from_tip ^ reach_from_base) { 1084 if (reach_from_base) 1085 counts[i].behind++; 1086 else 1087 counts[i].ahead++; 1088 } 1089 } 1090 1091 for (p = c->parents; p; p = p->next) { 1092 struct bitmap *bitmap_p; 1093 1094 repo_parse_commit(r, p->item); 1095 1096 bitmap_p = get_bit_array(p->item, width); 1097 bitmap_or(bitmap_p, bitmap_c); 1098 1099 /* 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 1104 * queue is STALE. 1105 */ 1106 if (bitmap_popcount(bitmap_p) == commits_nr) 1107 p->item->object.flags |= STALE; 1108 1109 insert_no_dup(&queue, p->item); 1110 } 1111 1112 free_bit_array(c); 1113 } 1114 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); 1119 free_bit_array(c); 1120 } 1121 clear_bit_arrays(&bit_arrays); 1122 clear_prio_queue(&queue); 1123} 1124 1125struct commit_and_index { 1126 struct commit *commit; 1127 unsigned int index; 1128 timestamp_t generation; 1129}; 1130 1131static int compare_commit_and_index_by_generation(const void *va, const void *vb) 1132{ 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; 1135 1136 if (a->generation > b->generation) 1137 return 1; 1138 if (a->generation < b->generation) 1139 return -1; 1140 return 0; 1141} 1142 1143void tips_reachable_from_bases(struct repository *r, 1144 struct commit_list *bases, 1145 struct commit **tips, size_t tips_nr, 1146 int mark) 1147{ 1148 struct commit_and_index *commits; 1149 size_t min_generation_index = 0; 1150 timestamp_t min_generation; 1151 struct commit_list *stack = NULL; 1152 1153 if (!bases || !tips || !tips_nr) 1154 return; 1155 1156 /* 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. 1161 */ 1162 1163 CALLOC_ARRAY(commits, tips_nr); 1164 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]); 1169 } 1170 1171 /* Sort with generation number ascending. */ 1172 QSORT(commits, tips_nr, compare_commit_and_index_by_generation); 1173 min_generation = commits[0].generation; 1174 1175 while (bases) { 1176 repo_parse_commit(r, bases->item); 1177 commit_list_insert(bases->item, &stack); 1178 bases = bases->next; 1179 } 1180 1181 while (stack) { 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); 1186 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) 1190 break; 1191 1192 if (commits[j].commit == c) { 1193 tips[commits[j].index]->object.flags |= mark; 1194 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)) 1199 k++; 1200 1201 /* Terminate early if all found. */ 1202 if (k >= tips_nr) 1203 goto done; 1204 1205 min_generation_index = k; 1206 min_generation = commits[k].generation; 1207 } 1208 } 1209 } 1210 1211 for (p = c->parents; p; p = p->next) { 1212 repo_parse_commit(r, p->item); 1213 1214 /* Have we already explored this parent? */ 1215 if (p->item->object.flags & SEEN) 1216 continue; 1217 1218 /* Is it below the current minimum generation? */ 1219 if (commit_graph_generation(p->item) < min_generation) 1220 continue; 1221 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); 1226 break; 1227 } 1228 1229 if (explored_all_parents) 1230 pop_commit(&stack); 1231 } 1232 1233done: 1234 free(commits); 1235 repo_clear_commit_marks(r, SEEN); 1236 free_commit_list(stack); 1237} 1238 1239/* 1240 * This slab initializes integers to zero, so use "-1" for "tip is best" and 1241 * "i + 1" for "bases[i] is best". 1242 */ 1243define_commit_slab(best_branch_base, int); 1244static 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)) 1247 1248int get_branch_base_for_tip(struct repository *r, 1249 struct commit *tip, 1250 struct commit **bases, 1251 size_t bases_nr) 1252{ 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; 1257 1258 if (!bases_nr) 1259 return -1; 1260 1261 repo_parse_commit(r, tip); 1262 if (commit_graph_generation(tip) == GENERATION_NUMBER_INFINITY) 1263 found_missing_gen = 1; 1264 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; 1271 } 1272 1273 if (found_missing_gen) { 1274 struct commit **commits; 1275 size_t commits_nr = bases_nr + 1; 1276 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); 1281 free(commits); 1282 } 1283 1284 /* Initialize queue and slab now that generations are guaranteed. */ 1285 init_best_branch_base(&best_branch_base); 1286 set_best(tip, -1); 1287 prio_queue_put(&queue, tip); 1288 1289 for (size_t i = 0; i < bases_nr; i++) { 1290 struct commit *c = bases[i]; 1291 int best = get_best(c); 1292 1293 /* Has this already been marked as best by another commit? */ 1294 if (best) { 1295 if (best == -1) { 1296 /* We agree at this position. Stop now. */ 1297 best_index = i + 1; 1298 goto cleanup; 1299 } 1300 continue; 1301 } 1302 1303 set_best(c, i + 1); 1304 prio_queue_put(&queue, c); 1305 } 1306 1307 while (queue.nr) { 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; 1312 1313 /* Have we reached a known branch point? It's optimal. */ 1314 if (c == branch_point) 1315 break; 1316 1317 repo_parse_commit(r, c); 1318 if (!c->parents) 1319 continue; 1320 1321 parent = c->parents->item; 1322 repo_parse_commit(r, parent); 1323 best_for_p = get_best(parent); 1324 1325 if (!best_for_p) { 1326 /* 'parent' is new, so pass along best_for_c. */ 1327 set_best(parent, best_for_c); 1328 prio_queue_put(&queue, parent); 1329 continue; 1330 } 1331 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); 1336 continue; 1337 } 1338 1339 /* 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. 1343 * 1344 * Update 'best_index' to match the minimum of all base indices 1345 * to reach 'parent'. 1346 */ 1347 1348 /* Exactly one is positive due to initial conditions. */ 1349 positive = (best_for_c < 0) ? best_for_p : best_for_c; 1350 1351 if (best_index < 0 || positive < best_index) 1352 best_index = positive; 1353 1354 /* No matter what, track that the parent is reachable from tip. */ 1355 set_best(parent, -1); 1356 branch_point = parent; 1357 } 1358 1359cleanup: 1360 clear_best_branch_base(&best_branch_base); 1361 clear_prio_queue(&queue); 1362 return best_index > 0 ? best_index - 1 : -1; 1363}