diff --git a/commit-reach.c b/commit-reach.c index 399f2a8673..2ea84d3dc0 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -234,15 +234,27 @@ static int remove_redundant_with_gen(struct repository *r, { int i, count_non_stale = 0, count_still_independent = cnt; timestamp_t min_generation = GENERATION_NUMBER_INFINITY; - struct commit **walk_start; + struct commit **walk_start, **sorted; size_t walk_start_nr = 0, walk_start_alloc = cnt; + int min_gen_pos = 0; + + /* + * Sort the input by generation number, ascending. This allows + * us to increase the "min_generation" limit when we discover + * the commit with lowest generation is STALE. The index + * min_gen_pos points to the current position within 'array' + * that is not yet known to be STALE. + */ + ALLOC_ARRAY(sorted, cnt); + COPY_ARRAY(sorted, array, cnt); + QSORT(sorted, cnt, compare_commits_by_gen); + min_generation = commit_graph_generation(sorted[0]); ALLOC_ARRAY(walk_start, walk_start_alloc); /* Mark all parents of the input as STALE */ for (i = 0; i < cnt; i++) { struct commit_list *parents; - timestamp_t generation; repo_parse_commit(r, array[i]); array[i]->object.flags |= RESULT; @@ -257,11 +269,6 @@ static int remove_redundant_with_gen(struct repository *r, } parents = parents->next; } - - generation = commit_graph_generation(array[i]); - - if (generation < min_generation) - min_generation = generation; } QSORT(walk_start, walk_start_nr, compare_commits_by_gen); @@ -293,6 +300,12 @@ static int remove_redundant_with_gen(struct repository *r, c->object.flags &= ~RESULT; if (--count_still_independent <= 1) break; + if (oideq(&c->object.oid, &sorted[min_gen_pos]->object.oid)) { + while (min_gen_pos < cnt - 1 && + (sorted[min_gen_pos]->object.flags & STALE)) + min_gen_pos++; + min_generation = commit_graph_generation(sorted[min_gen_pos]); + } } if (commit_graph_generation(c) < min_generation) { @@ -316,6 +329,7 @@ static int remove_redundant_with_gen(struct repository *r, } free_commit_list(stack); } + free(sorted); /* clear result */ for (i = 0; i < cnt; i++)