use commit_stack instead of prio_queue in LIFO mode

A prio_queue with a NULL compare function acts as a stack -- the last element in is the first one out (LIFO). Use an actual commit_stack instead where possible, as it documents the behavior better, provides type safety and saves some memory because prio_queue stores an additional tie-breaking counter per element. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Mar 17, 2026 at 22:40 UTC 1ae7a359ae53e98f153b8fb0dea532d2007a0093
3 files changed +17 -19
builtin/name-rev.c
+7 -9
@@ -12,7 +12,6 @@
12 #include "object-name.h"
13 #include "pager.h"
14 #include "parse-options.h"
15 -#include "prio-queue.h"
15 #include "hash-lookup.h"
16 #include "commit-slab.h"
17 #include "commit-graph.h"
@@ -178,7 +177,7 @@ static void name_rev(struct commit *start_commit,
177 const char *tip_name, timestamp_t taggerdate,
178 int from_tag, int deref, struct mem_pool *string_pool)
179 {
181 - struct prio_queue queue;
180 + struct commit_stack stack = COMMIT_STACK_INIT;
181 struct commit *commit;
182 struct commit_stack parents_to_queue = COMMIT_STACK_INIT;
183 struct rev_name *start_name;
@@ -197,10 +196,9 @@ static void name_rev(struct commit *start_commit,
196 else
197 start_name->tip_name = mem_pool_strdup(string_pool, tip_name);
198
200 - memset(&queue, 0, sizeof(queue)); /* Use the prio_queue as LIFO */
201 - prio_queue_put(&queue, start_commit);
199 + commit_stack_push(&stack, start_commit);
200
203 - while ((commit = prio_queue_get(&queue))) {
201 + while ((commit = commit_stack_pop(&stack))) {
202 struct rev_name *name = get_commit_rev_name(commit);
203 struct commit_list *parents;
204 int parent_number = 1;
@@ -241,13 +239,13 @@ static void name_rev(struct commit *start_commit,
239 }
240 }
241
244 - /* The first parent must come out first from the prio_queue */
242 + /* The first parent must come out first from the stack */
243 while (parents_to_queue.nr)
246 - prio_queue_put(&queue,
247 - commit_stack_pop(&parents_to_queue));
244 + commit_stack_push(&stack,
245 + commit_stack_pop(&parents_to_queue));
246 }
247
250 - clear_prio_queue(&queue);
248 + commit_stack_clear(&stack);
249 commit_stack_clear(&parents_to_queue);
250 }
251
negotiator/default.c
+5 -5
@@ -57,19 +57,19 @@ static int clear_marks(const struct reference *ref, void *cb_data UNUSED)
57 static void mark_common(struct negotiation_state *ns, struct commit *commit,
58 int ancestors_only, int dont_parse)
59 {
60 - struct prio_queue queue = { NULL };
60 + struct commit_stack stack = COMMIT_STACK_INIT;
61
62 if (!commit || (commit->object.flags & COMMON))
63 return;
64
65 - prio_queue_put(&queue, commit);
65 + commit_stack_push(&stack, commit);
66 if (!ancestors_only) {
67 commit->object.flags |= COMMON;
68
69 if ((commit->object.flags & SEEN) && !(commit->object.flags & POPPED))
70 ns->non_common_revs--;
71 }
72 - while ((commit = prio_queue_get(&queue))) {
72 + while ((commit = commit_stack_pop(&stack))) {
73 struct object *o = (struct object *)commit;
74
75 if (!(o->flags & SEEN))
@@ -94,12 +94,12 @@ static void mark_common(struct negotiation_state *ns, struct commit *commit,
94 if ((p->object.flags & SEEN) && !(p->object.flags & POPPED))
95 ns->non_common_revs--;
96
97 - prio_queue_put(&queue, parents->item);
97 + commit_stack_push(&stack, parents->item);
98 }
99 }
100 }
101
102 - clear_prio_queue(&queue);
102 + commit_stack_clear(&stack);
103 }
104
105 /*
negotiator/skipping.c
+5 -5
@@ -91,15 +91,15 @@ static int clear_marks(const struct reference *ref, void *cb_data UNUSED)
91 */
92 static void mark_common(struct data *data, struct commit *seen_commit)
93 {
94 - struct prio_queue queue = { NULL };
94 + struct commit_stack stack = COMMIT_STACK_INIT;
95 struct commit *c;
96
97 if (seen_commit->object.flags & COMMON)
98 return;
99
100 - prio_queue_put(&queue, seen_commit);
100 + commit_stack_push(&stack, seen_commit);
101 seen_commit->object.flags |= COMMON;
102 - while ((c = prio_queue_get(&queue))) {
102 + while ((c = commit_stack_pop(&stack))) {
103 struct commit_list *p;
104
105 if (!(c->object.flags & POPPED))
@@ -113,11 +113,11 @@ static void mark_common(struct data *data, struct commit *seen_commit)
113 continue;
114
115 p->item->object.flags |= COMMON;
116 - prio_queue_put(&queue, p->item);
116 + commit_stack_push(&stack, p->item);
117 }
118 }
119
120 - clear_prio_queue(&queue);
120 + commit_stack_clear(&stack);
121 }
122
123 /*