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 repository *r,
 
  34                                                 struct commit *one, int n,
 
  38         struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
 
  39         struct commit_list *result = NULL;
 
  41         uint32_t last_gen = GENERATION_NUMBER_INFINITY;
 
  44                 queue.compare = compare_commits_by_commit_date;
 
  46         one->object.flags |= PARENT1;
 
  48                 commit_list_append(one, &result);
 
  51         prio_queue_put(&queue, one);
 
  53         for (i = 0; i < n; i++) {
 
  54                 twos[i]->object.flags |= PARENT2;
 
  55                 prio_queue_put(&queue, twos[i]);
 
  58         while (queue_has_nonstale(&queue)) {
 
  59                 struct commit *commit = prio_queue_get(&queue);
 
  60                 struct commit_list *parents;
 
  63                 if (min_generation && commit->generation > last_gen)
 
  64                         BUG("bad generation skip %8x > %8x at %s",
 
  65                             commit->generation, last_gen,
 
  66                             oid_to_hex(&commit->object.oid));
 
  67                 last_gen = commit->generation;
 
  69                 if (commit->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 = array[i]->generation;
 
 184                 for (j = filled = 0; j < cnt; j++) {
 
 185                         if (i == j || redundant[j])
 
 187                         filled_index[filled] = j;
 
 188                         work[filled++] = array[j];
 
 190                         if (array[j]->generation < min_generation)
 
 191                                 min_generation = array[j]->generation;
 
 193                 common = paint_down_to_common(r, array[i], filled,
 
 194                                               work, min_generation);
 
 195                 if (array[i]->object.flags & PARENT2)
 
 197                 for (j = 0; j < filled; j++)
 
 198                         if (work[j]->object.flags & PARENT1)
 
 199                                 redundant[filled_index[j]] = 1;
 
 200                 clear_commit_marks(array[i], all_flags);
 
 201                 clear_commit_marks_many(filled, work, all_flags);
 
 202                 free_commit_list(common);
 
 205         /* Now collect the result */
 
 206         COPY_ARRAY(work, array, cnt);
 
 207         for (i = filled = 0; i < cnt; i++)
 
 209                         array[filled++] = work[i];
 
 210         for (j = filled, i = 0; i < cnt; i++)
 
 212                         array[j++] = work[i];
 
 219 static struct commit_list *get_merge_bases_many_0(struct repository *r,
 
 222                                                   struct commit **twos,
 
 225         struct commit_list *list;
 
 226         struct commit **rslt;
 
 227         struct commit_list *result;
 
 230         result = merge_bases_many(r, one, n, twos);
 
 231         for (i = 0; i < n; i++) {
 
 235         if (!result || !result->next) {
 
 237                         clear_commit_marks(one, all_flags);
 
 238                         clear_commit_marks_many(n, twos, all_flags);
 
 243         /* There are more than one */
 
 244         cnt = commit_list_count(result);
 
 245         rslt = xcalloc(cnt, sizeof(*rslt));
 
 246         for (list = result, i = 0; list; list = list->next)
 
 247                 rslt[i++] = list->item;
 
 248         free_commit_list(result);
 
 250         clear_commit_marks(one, all_flags);
 
 251         clear_commit_marks_many(n, twos, all_flags);
 
 253         cnt = remove_redundant(r, rslt, cnt);
 
 255         for (i = 0; i < cnt; i++)
 
 256                 commit_list_insert_by_date(rslt[i], &result);
 
 261 struct commit_list *repo_get_merge_bases_many(struct repository *r,
 
 264                                               struct commit **twos)
 
 266         return get_merge_bases_many_0(r, one, n, twos, 1);
 
 269 struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
 
 272                                                     struct commit **twos)
 
 274         return get_merge_bases_many_0(r, one, n, twos, 0);
 
 277 struct commit_list *repo_get_merge_bases(struct repository *r,
 
 281         return get_merge_bases_many_0(r, one, 1, &two, 1);
 
 285  * Is "commit" a descendant of one of the elements on the "with_commit" list?
 
 287 int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
 
 292         if (generation_numbers_enabled(the_repository)) {
 
 293                 struct commit_list *from_list = NULL;
 
 295                 commit_list_insert(commit, &from_list);
 
 296                 result = can_all_from_reach(from_list, with_commit, 0);
 
 297                 free_commit_list(from_list);
 
 300                 while (with_commit) {
 
 301                         struct commit *other;
 
 303                         other = with_commit->item;
 
 304                         with_commit = with_commit->next;
 
 305                         if (in_merge_bases(other, commit))
 
 313  * Is "commit" an ancestor of one of the "references"?
 
 315 int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
 
 316                              int nr_reference, struct commit **reference)
 
 318         struct commit_list *bases;
 
 320         uint32_t min_generation = GENERATION_NUMBER_INFINITY;
 
 322         if (repo_parse_commit(r, commit))
 
 324         for (i = 0; i < nr_reference; i++) {
 
 325                 if (repo_parse_commit(r, reference[i]))
 
 327                 if (reference[i]->generation < min_generation)
 
 328                         min_generation = reference[i]->generation;
 
 331         if (commit->generation > min_generation)
 
 334         bases = paint_down_to_common(r, commit,
 
 335                                      nr_reference, reference,
 
 337         if (commit->object.flags & PARENT2)
 
 339         clear_commit_marks(commit, all_flags);
 
 340         clear_commit_marks_many(nr_reference, reference, all_flags);
 
 341         free_commit_list(bases);
 
 346  * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
 
 348 int repo_in_merge_bases(struct repository *r,
 
 349                         struct commit *commit,
 
 350                         struct commit *reference)
 
 352         return repo_in_merge_bases_many(r, commit, 1, &reference);
 
 355 struct commit_list *reduce_heads(struct commit_list *heads)
 
 357         struct commit_list *p;
 
 358         struct commit_list *result = NULL, **tail = &result;
 
 359         struct commit **array;
 
 366         for (p = heads; p; p = p->next)
 
 367                 p->item->object.flags &= ~STALE;
 
 368         for (p = heads, num_head = 0; p; p = p->next) {
 
 369                 if (p->item->object.flags & STALE)
 
 371                 p->item->object.flags |= STALE;
 
 374         array = xcalloc(num_head, sizeof(*array));
 
 375         for (p = heads, i = 0; p; p = p->next) {
 
 376                 if (p->item->object.flags & STALE) {
 
 377                         array[i++] = p->item;
 
 378                         p->item->object.flags &= ~STALE;
 
 381         num_head = remove_redundant(the_repository, array, num_head);
 
 382         for (i = 0; i < num_head; i++)
 
 383                 tail = &commit_list_insert(array[i], tail)->next;
 
 388 void reduce_heads_replace(struct commit_list **heads)
 
 390         struct commit_list *result = reduce_heads(*heads);
 
 391         free_commit_list(*heads);
 
 395 int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
 
 398         struct commit *old_commit, *new_commit;
 
 399         struct commit_list *old_commit_list = NULL;
 
 402          * Both new_commit and old_commit must be commit-ish and new_commit is descendant of
 
 403          * old_commit.  Otherwise we require --force.
 
 405         o = deref_tag(the_repository, parse_object(the_repository, old_oid),
 
 407         if (!o || o->type != OBJ_COMMIT)
 
 409         old_commit = (struct commit *) o;
 
 411         o = deref_tag(the_repository, parse_object(the_repository, new_oid),
 
 413         if (!o || o->type != OBJ_COMMIT)
 
 415         new_commit = (struct commit *) o;
 
 417         if (parse_commit(new_commit) < 0)
 
 420         commit_list_insert(old_commit, &old_commit_list);
 
 421         return is_descendant_of(new_commit, old_commit_list);
 
 425  * Mimicking the real stack, this stack lives on the heap, avoiding stack
 
 428  * At each recursion step, the stack items points to the commits whose
 
 429  * ancestors are to be inspected.
 
 431 struct contains_stack {
 
 433         struct contains_stack_entry {
 
 434                 struct commit *commit;
 
 435                 struct commit_list *parents;
 
 439 static int in_commit_list(const struct commit_list *want, struct commit *c)
 
 441         for (; want; want = want->next)
 
 442                 if (oideq(&want->item->object.oid, &c->object.oid))
 
 448  * Test whether the candidate is contained in the list.
 
 449  * Do not recurse to find out, though, but return -1 if inconclusive.
 
 451 static enum contains_result contains_test(struct commit *candidate,
 
 452                                           const struct commit_list *want,
 
 453                                           struct contains_cache *cache,
 
 456         enum contains_result *cached = contains_cache_at(cache, candidate);
 
 458         /* If we already have the answer cached, return that. */
 
 463         if (in_commit_list(want, candidate)) {
 
 464                 *cached = CONTAINS_YES;
 
 468         /* Otherwise, we don't know; prepare to recurse */
 
 469         parse_commit_or_die(candidate);
 
 471         if (candidate->generation < cutoff)
 
 474         return CONTAINS_UNKNOWN;
 
 477 static void push_to_contains_stack(struct commit *candidate, struct contains_stack *contains_stack)
 
 479         ALLOC_GROW(contains_stack->contains_stack, contains_stack->nr + 1, contains_stack->alloc);
 
 480         contains_stack->contains_stack[contains_stack->nr].commit = candidate;
 
 481         contains_stack->contains_stack[contains_stack->nr++].parents = candidate->parents;
 
 484 static enum contains_result contains_tag_algo(struct commit *candidate,
 
 485                                               const struct commit_list *want,
 
 486                                               struct contains_cache *cache)
 
 488         struct contains_stack contains_stack = { 0, 0, NULL };
 
 489         enum contains_result result;
 
 490         uint32_t cutoff = GENERATION_NUMBER_INFINITY;
 
 491         const struct commit_list *p;
 
 493         for (p = want; p; p = p->next) {
 
 494                 struct commit *c = p->item;
 
 495                 load_commit_graph_info(the_repository, c);
 
 496                 if (c->generation < cutoff)
 
 497                         cutoff = c->generation;
 
 500         result = contains_test(candidate, want, cache, cutoff);
 
 501         if (result != CONTAINS_UNKNOWN)
 
 504         push_to_contains_stack(candidate, &contains_stack);
 
 505         while (contains_stack.nr) {
 
 506                 struct contains_stack_entry *entry = &contains_stack.contains_stack[contains_stack.nr - 1];
 
 507                 struct commit *commit = entry->commit;
 
 508                 struct commit_list *parents = entry->parents;
 
 511                         *contains_cache_at(cache, commit) = CONTAINS_NO;
 
 515                  * If we just popped the stack, parents->item has been marked,
 
 516                  * therefore contains_test will return a meaningful yes/no.
 
 518                 else switch (contains_test(parents->item, want, cache, cutoff)) {
 
 520                         *contains_cache_at(cache, commit) = CONTAINS_YES;
 
 524                         entry->parents = parents->next;
 
 526                 case CONTAINS_UNKNOWN:
 
 527                         push_to_contains_stack(parents->item, &contains_stack);
 
 531         free(contains_stack.contains_stack);
 
 532         return contains_test(candidate, want, cache, cutoff);
 
 535 int commit_contains(struct ref_filter *filter, struct commit *commit,
 
 536                     struct commit_list *list, struct contains_cache *cache)
 
 538         if (filter->with_commit_tag_algo)
 
 539                 return contains_tag_algo(commit, list, cache) == CONTAINS_YES;
 
 540         return is_descendant_of(commit, list);
 
 543 static int compare_commits_by_gen(const void *_a, const void *_b)
 
 545         const struct commit *a = *(const struct commit * const *)_a;
 
 546         const struct commit *b = *(const struct commit * const *)_b;
 
 548         if (a->generation < b->generation)
 
 550         if (a->generation > b->generation)
 
 555 int can_all_from_reach_with_flag(struct object_array *from,
 
 556                                  unsigned int with_flag,
 
 557                                  unsigned int assign_flag,
 
 558                                  time_t min_commit_date,
 
 559                                  uint32_t min_generation)
 
 561         struct commit **list = NULL;
 
 566         ALLOC_ARRAY(list, from->nr);
 
 568         for (i = 0; i < from->nr; i++) {
 
 569                 struct object *from_one = from->objects[i].item;
 
 571                 if (!from_one || from_one->flags & assign_flag)
 
 574                 from_one = deref_tag(the_repository, from_one,
 
 576                 if (!from_one || from_one->type != OBJ_COMMIT) {
 
 578                          * no way to tell if this is reachable by
 
 579                          * looking at the ancestry chain alone, so
 
 580                          * leave a note to ourselves not to worry about
 
 581                          * this object anymore.
 
 583                         from->objects[i].item->flags |= assign_flag;
 
 587                 list[nr_commits] = (struct commit *)from_one;
 
 588                 if (parse_commit(list[nr_commits]) ||
 
 589                     list[nr_commits]->generation < min_generation) {
 
 597         QSORT(list, nr_commits, compare_commits_by_gen);
 
 599         for (i = 0; i < nr_commits; i++) {
 
 600                 /* DFS from list[i] */
 
 601                 struct commit_list *stack = NULL;
 
 603                 list[i]->object.flags |= assign_flag;
 
 604                 commit_list_insert(list[i], &stack);
 
 607                         struct commit_list *parent;
 
 609                         if (stack->item->object.flags & (with_flag | RESULT)) {
 
 612                                         stack->item->object.flags |= RESULT;
 
 616                         for (parent = stack->item->parents; parent; parent = parent->next) {
 
 617                                 if (parent->item->object.flags & (with_flag | RESULT))
 
 618                                         stack->item->object.flags |= RESULT;
 
 620                                 if (!(parent->item->object.flags & assign_flag)) {
 
 621                                         parent->item->object.flags |= assign_flag;
 
 623                                         if (parse_commit(parent->item) ||
 
 624                                             parent->item->date < min_commit_date ||
 
 625                                             parent->item->generation < min_generation)
 
 628                                         commit_list_insert(parent->item, &stack);
 
 637                 if (!(list[i]->object.flags & (with_flag | RESULT))) {
 
 644         clear_commit_marks_many(nr_commits, list, RESULT | assign_flag);
 
 647         for (i = 0; i < from->nr; i++)
 
 648                 from->objects[i].item->flags &= ~assign_flag;
 
 653 int can_all_from_reach(struct commit_list *from, struct commit_list *to,
 
 654                        int cutoff_by_min_date)
 
 656         struct object_array from_objs = OBJECT_ARRAY_INIT;
 
 657         time_t min_commit_date = cutoff_by_min_date ? from->item->date : 0;
 
 658         struct commit_list *from_iter = from, *to_iter = to;
 
 660         uint32_t min_generation = GENERATION_NUMBER_INFINITY;
 
 663                 add_object_array(&from_iter->item->object, NULL, &from_objs);
 
 665                 if (!parse_commit(from_iter->item)) {
 
 666                         if (from_iter->item->date < min_commit_date)
 
 667                                 min_commit_date = from_iter->item->date;
 
 669                         if (from_iter->item->generation < min_generation)
 
 670                                 min_generation = from_iter->item->generation;
 
 673                 from_iter = from_iter->next;
 
 677                 if (!parse_commit(to_iter->item)) {
 
 678                         if (to_iter->item->date < min_commit_date)
 
 679                                 min_commit_date = to_iter->item->date;
 
 681                         if (to_iter->item->generation < min_generation)
 
 682                                 min_generation = to_iter->item->generation;
 
 685                 to_iter->item->object.flags |= PARENT2;
 
 687                 to_iter = to_iter->next;
 
 690         result = can_all_from_reach_with_flag(&from_objs, PARENT2, PARENT1,
 
 691                                               min_commit_date, min_generation);
 
 694                 clear_commit_marks(from->item, PARENT1);
 
 699                 clear_commit_marks(to->item, PARENT2);
 
 703         object_array_clear(&from_objs);
 
 707 struct commit_list *get_reachable_subset(struct commit **from, int nr_from,
 
 708                                          struct commit **to, int nr_to,
 
 709                                          unsigned int reachable_flag)
 
 711         struct commit **item;
 
 712         struct commit *current;
 
 713         struct commit_list *found_commits = NULL;
 
 714         struct commit **to_last = to + nr_to;
 
 715         struct commit **from_last = from + nr_from;
 
 716         uint32_t min_generation = GENERATION_NUMBER_INFINITY;
 
 719         struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
 
 721         for (item = to; item < to_last; item++) {
 
 722                 struct commit *c = *item;
 
 725                 if (c->generation < min_generation)
 
 726                         min_generation = c->generation;
 
 728                 if (!(c->object.flags & PARENT1)) {
 
 729                         c->object.flags |= PARENT1;
 
 734         for (item = from; item < from_last; item++) {
 
 735                 struct commit *c = *item;
 
 736                 if (!(c->object.flags & PARENT2)) {
 
 737                         c->object.flags |= PARENT2;
 
 740                         prio_queue_put(&queue, *item);
 
 744         while (num_to_find && (current = prio_queue_get(&queue)) != NULL) {
 
 745                 struct commit_list *parents;
 
 747                 if (current->object.flags & PARENT1) {
 
 748                         current->object.flags &= ~PARENT1;
 
 749                         current->object.flags |= reachable_flag;
 
 750                         commit_list_insert(current, &found_commits);
 
 754                 for (parents = current->parents; parents; parents = parents->next) {
 
 755                         struct commit *p = parents->item;
 
 759                         if (p->generation < min_generation)
 
 762                         if (p->object.flags & PARENT2)
 
 765                         p->object.flags |= PARENT2;
 
 766                         prio_queue_put(&queue, p);
 
 770         clear_commit_marks_many(nr_to, to, PARENT1);
 
 771         clear_commit_marks_many(nr_from, from, PARENT2);
 
 773         return found_commits;