diff --git a/commit-reach.c b/commit-reach.c index d3a9b3ed6f..31e6110b13 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -17,8 +17,9 @@ #define PARENT2 (1u<<17) #define STALE (1u<<18) #define RESULT (1u<<19) +#define ENQUEUED (1u<<20) -static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT); +static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT | ENQUEUED); static int compare_commits_by_gen(const void *_a, const void *_b) { @@ -39,6 +40,22 @@ static int compare_commits_by_gen(const void *_a, const void *_b) return 0; } +static void prio_queue_put_dedup(struct prio_queue *queue, struct commit *c) +{ + if (c->object.flags & ENQUEUED) + return; + c->object.flags |= ENQUEUED; + prio_queue_put(queue, c); +} + +static struct commit *prio_queue_get_dedup(struct prio_queue *queue) +{ + struct commit *commit = prio_queue_get(queue); + if (commit) + commit->object.flags &= ~ENQUEUED; + return commit; +} + static int queue_has_nonstale(struct prio_queue *queue) { for (size_t i = 0; i < queue->nr; i++) { @@ -70,15 +87,15 @@ static int paint_down_to_common(struct repository *r, commit_list_append(one, result); return 0; } - prio_queue_put(&queue, one); + prio_queue_put_dedup(&queue, one); for (i = 0; i < n; i++) { twos[i]->object.flags |= PARENT2; - prio_queue_put(&queue, twos[i]); + prio_queue_put_dedup(&queue, twos[i]); } while (queue_has_nonstale(&queue)) { - struct commit *commit = prio_queue_get(&queue); + struct commit *commit = prio_queue_get_dedup(&queue); struct commit_list *parents; int flags; timestamp_t generation = commit_graph_generation(commit); @@ -124,7 +141,7 @@ static int paint_down_to_common(struct repository *r, oid_to_hex(&p->object.oid)); } p->object.flags |= flags; - prio_queue_put(&queue, p); + prio_queue_put_dedup(&queue, p); } } diff --git a/object.h b/object.h index 2b26de3044..8fb03ff90a 100644 --- a/object.h +++ b/object.h @@ -75,7 +75,7 @@ void object_array_init(struct object_array *array); * bundle.c: 16 * http-push.c: 11-----14 * commit-graph.c: 15 - * commit-reach.c: 16-----19 + * commit-reach.c: 16-------20 * builtin/last-modified.c: 1617 * object-name.c: 20 * list-objects-filter.c: 21