git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v7 07/10] commit-reach: introduce struct paint_state with per-side counters

From
Kristofer Karlsson via GitGitGadget <gitgitgadget@gmail.com>
Date
Aug 6, 2026, 10:59 UTC
Message-ID
<a1c8e89ef9f1d0fb5cb10ec9687633df8792ec7b.1786013982.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.2149.v7.git.1786013982.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>

Add a paint_state struct for use by paint_down_to_common() that wraps a prio_queue with per-side commit counters. Each non-stale queued commit occupies exactly one counter bucket based on its paint flags: PARENT1-only, PARENT2-only, or both sides (a pending merge-base candidate).

The counters are maintained by paint_count_update() which adjusts the appropriate bucket by a signed delta. An exhaustive switch on the paint+stale bits documents all valid flag combinations in one place.

Convert paint_down_to_common() to use paint_state. The loop now drains the queue via paint_queue_get() which returns NULL when all counters reach zero, replacing the old pointer-based termination (max_nonstale). This is equivalent behavior -- both conditions detect that no non-stale entries remain.

paint_queue_get() uses a "pop first" form: it dequeues a commit, then checks the counters. This means the loop exits one iteration earlier than the old code in some topologies (the popped stale commit is never processed), so a few step counts drop by one.

The existing nonstale_queue is left in place for ahead_behind(), though nonstale_queue_put_dedup() and nonstale_queue_get_dedup() became unused and are removed.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
 .../technical/paint-down-to-common.adoc       |   9 +-
 commit-reach.c                                | 103 +++++++++++++-----
 t/t6600-test-reach.sh                         |   6 +-
 3 files changed, 82 insertions(+), 36 deletions(-)
diff --git a/Documentation/technical/paint-down-to-common.adoc b/Documentation/technical/paint-down-to-common.adoc
index cea0cc2f91..37fa6f93c1 100644
--- a/Documentation/technical/paint-down-to-common.adoc
+++ b/Documentation/technical/paint-down-to-common.adoc
@@ -103,15 +103,12 @@ re-enqueued is bounded by the number of flag transitions.
 Termination
 -----------
 
-The walk uses a `nonstale_queue` wrapper around `prio_queue` that
-tracks `max_nonstale`: the lowest-priority non-stale commit enqueued
-so far. Once that commit is dequeued, every remaining entry is known
-to be STALE and the loop terminates. Specifically, the main loop
+The walk tracks the number of commits of each type in the queue
+(PARENT1-only, PARENT2-only, pending merge-base). The main loop
 ends when one of the following conditions holds:
 
   1. The queue is empty.
-  2. `max_nonstale` has been dequeued, meaning the queue only contains
-     STALE entries.
+  2. The queue contains only stale entries.
   3. Generation cutoff: the dequeued commit's generation is below
      a caller-supplied `min_generation` threshold.
   4. Single result: the caller only needs one merge base, one has
diff --git a/commit-reach.c b/commit-reach.c
index d59e76a2e2..a62b5e4624 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -79,21 +79,73 @@ static void clear_nonstale_queue(struct nonstale_queue *queue)
 	queue->max_nonstale = NULL;
 }
 
-static void nonstale_queue_put_dedup(struct nonstale_queue *queue,
-				     struct commit *c)
+/*
+ * Priority queue with per-side commit counters for paint_down_to_common().
+ * Each non-stale queued commit occupies exactly one bucket: PARENT1-only,
+ * PARENT2-only, or both (a pending merge-base candidate).
+ */
+struct paint_state {
+	struct prio_queue queue;
+	size_t parent1_count;
+	size_t parent2_count;
+	size_t mb_candidate_count;
+	int gen_ordered;
+};
+
+static void paint_count_update(struct paint_state *state,
+			       unsigned flags, int delta)
 {
-	if (c->object.flags & ENQUEUED)
-		return;
-	c->object.flags |= ENQUEUED;
-	nonstale_queue_put(queue, c);
+	switch (flags & (PARENT1 | PARENT2 | STALE)) {
+	case PARENT1:
+		state->parent1_count += delta;
+		break;
+
+	case PARENT2:
+		state->parent2_count += delta;
+		break;
+
+	case PARENT1 | PARENT2:
+		state->mb_candidate_count += delta;
+		break;
+
+	case PARENT1 | PARENT2 | STALE:
+		break;
+
+	default:
+		BUG("unexpected paint state");
+	}
+}
+
+static void paint_queue_put(struct paint_state *state,
+			    struct commit *c, unsigned add_flags)
+{
+	unsigned old_flags = c->object.flags;
+	c->object.flags |= add_flags;
+
+	if (old_flags & ENQUEUED) {
+		paint_count_update(state, old_flags, -1);
+		paint_count_update(state, c->object.flags, 1);
+	} else {
+		c->object.flags |= ENQUEUED;
+		prio_queue_put(&state->queue, c);
+		paint_count_update(state, c->object.flags, 1);
+	}
 }
 
-static struct commit *nonstale_queue_get_dedup(struct nonstale_queue *queue)
+static struct commit *paint_queue_get(struct paint_state *state)
 {
-	struct commit *commit = nonstale_queue_get(queue);
+	struct commit *commit = prio_queue_get(&state->queue);
+
+	if (!commit)
+		return NULL;
+
+	commit->object.flags &= ~ENQUEUED;
+
+	if (!state->parent1_count && !state->parent2_count &&
+	    !state->mb_candidate_count)
+		return NULL;
 
-	if (commit)
-		commit->object.flags &= ~ENQUEUED;
+	paint_count_update(state, commit->object.flags, -1);
 	return commit;
 }
 
@@ -109,18 +161,19 @@ static int paint_down_to_common(struct repository *r,
 				enum merge_base_flags mb_flags,
 				struct commit_list **result)
 {
-	struct nonstale_queue queue = {
-		{ compare_commits_by_gen_then_commit_date }
+	struct paint_state state = {
+		.queue = { compare_commits_by_gen_then_commit_date },
+		.gen_ordered = 1,
 	};
+	struct commit *commit;
 	int i;
-	int gen_ordered = 1;
 	int steps = 0;
 	timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
 	struct commit_list **tail = result;
 
 	if (!min_generation && !corrected_commit_dates_enabled(r)) {
-		queue.pq.compare = compare_commits_by_commit_date;
-		gen_ordered = 0;
+		state.queue.compare = compare_commits_by_commit_date;
+		state.gen_ordered = 0;
 	}
 
 	one->object.flags |= PARENT1;
@@ -128,15 +181,12 @@ static int paint_down_to_common(struct repository *r,
 		commit_list_append(one, result);
 		return 0;
 	}
-	nonstale_queue_put_dedup(&queue, one);
+	paint_queue_put(&state, one, 0);
 
-	for (i = 0; i < n; i++) {
-		twos[i]->object.flags |= PARENT2;
-		nonstale_queue_put_dedup(&queue, twos[i]);
-	}
+	for (i = 0; i < n; i++)
+		paint_queue_put(&state, twos[i], PARENT2);
 
-	while (queue.max_nonstale) {
-		struct commit *commit = nonstale_queue_get_dedup(&queue);
+	while ((commit = paint_queue_get(&state))) {
 		struct commit_list *parents;
 		int flags;
 		timestamp_t generation = commit_graph_generation(commit);
@@ -162,7 +212,7 @@ static int paint_down_to_common(struct repository *r,
 				 * descendant of this one.
 				 */
 				if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
-				    gen_ordered &&
+				    state.gen_ordered &&
 				    generation < GENERATION_NUMBER_INFINITY)
 					break;
 			}
@@ -176,7 +226,7 @@ static int paint_down_to_common(struct repository *r,
 			if ((p->object.flags & flags) == flags)
 				continue;
 			if (repo_parse_commit(r, p)) {
-				clear_nonstale_queue(&queue);
+				clear_prio_queue(&state.queue);
 				commit_list_free(*result);
 				*result = NULL;
 				/*
@@ -191,12 +241,11 @@ static int paint_down_to_common(struct repository *r,
 				return error(_("could not parse commit %s"),
 					     oid_to_hex(&p->object.oid));
 			}
-			p->object.flags |= flags;
-			nonstale_queue_put_dedup(&queue, p);
+			paint_queue_put(&state, p, flags);
 		}
 	}
 
-	clear_nonstale_queue(&queue);
+	clear_prio_queue(&state.queue);
 	trace2_data_intmax("paint_down_to_common", r,
 			   "steps", steps);
 	commit_list_sort_by_date(result);
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index 55aa220bb3..f9895f5fd7 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -366,7 +366,7 @@ test_expect_success 'get_merge_bases_many:pending-stale' '
 		git rev-parse ps-B
 	} >expect &&
 	test_all_modes get_merge_bases_many &&
-	test_paint_down_steps 6 6 6 6
+	test_paint_down_steps 5 5 5 5
 '
 
 test_expect_success 'get_merge_bases_many:infinity-both-sides' '
@@ -381,7 +381,7 @@ test_expect_success 'get_merge_bases_many:infinity-both-sides' '
 		git rev-parse pi-B
 	} >expect &&
 	test_all_modes get_merge_bases_many &&
-	test_paint_down_steps 5 5 5 5
+	test_paint_down_steps 5 4 5 5
 '
 
 test_expect_success 'setup mixed finite/INFINITY topology' '
@@ -438,7 +438,7 @@ test_expect_success 'merge-base --all with clock skew and redundant ancestor (si
 	>input &&
 	git rev-parse se2-MB1 >expect &&
 	run_all_modes git merge-base --all se2-A se2-B &&
-	test_paint_down_steps 8 7 8 8
+	test_paint_down_steps 8 6 8 8
 '
 
 test_expect_success 'reduce_heads' '
-- 
gitgitgadget
Previous: Elijah NewrenNext: Elijah Newren
Message 148 of 176 in “commit-reach: terminate merge-base walk when one side is exhausted”
  1. 0/6 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jun 20, 2026
  2. 1/6 commit-reach: decouple ahead_behind from nonstale_queueKristofer Karlsson via GitGitGadget, Jun 20, 2026
  3. Derrick StoleeJun 22, 2026
  4. Kristofer KarlssonJun 22, 2026
  5. 2/6 commit-reach: introduce struct paint_queue with per-side countersKristofer Karlsson via GitGitGadget, Jun 20, 2026
  6. Derrick StoleeJun 22, 2026
  7. Kristofer KarlssonJun 22, 2026
  8. Derrick StoleeJun 22, 2026
  9. Kristofer KarlssonJun 23, 2026
  10. Derrick StoleeJun 23, 2026
  11. Kristofer KarlssonJun 23, 2026
  12. Derrick StoleeJun 23, 2026
  13. Kristofer KarlssonJun 24, 2026
  14. 3/6 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jun 20, 2026
  15. Derrick StoleeJun 22, 2026
  16. Kristofer KarlssonJun 22, 2026
  17. Derrick StoleeJun 22, 2026
  18. Kristofer KarlssonJun 22, 2026
  19. Derrick StoleeJun 23, 2026
  20. 4/6 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jun 20, 2026
  21. Derrick StoleeJun 22, 2026
  22. Kristofer KarlssonJun 22, 2026
  23. Derrick StoleeJun 22, 2026
  24. 5/6 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jun 20, 2026
  25. Derrick StoleeJun 22, 2026
  26. 6/6 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jun 20, 2026
  27. Derrick StoleeJun 22, 2026
  28. Kristofer KarlssonJun 22, 2026
  29. Derrick StoleeJun 22, 2026
  30. 0/7 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jun 24, 2026
  31. 1/7 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jun 24, 2026
  32. Junio C HamanoJun 24, 2026
  33. 2/7 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jun 24, 2026
  34. Derrick StoleeJun 24, 2026
  35. Kristofer KarlssonJun 24, 2026
  36. 3/7 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jun 24, 2026
  37. 4/7 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Jun 24, 2026
  38. Derrick StoleeJun 24, 2026
  39. Kristofer KarlssonJun 24, 2026
  40. 5/7 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Jun 24, 2026
  41. Derrick StoleeJun 24, 2026
  42. Kristofer KarlssonJun 24, 2026
  43. 6/7 commit-reach: remove unused nonstale_queue dedup wrappersKristofer Karlsson via GitGitGadget, Jun 24, 2026
  44. Derrick StoleeJun 24, 2026
  45. 7/7 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jun 24, 2026
  46. Derrick StoleeJun 24, 2026
  47. Kristofer KarlssonJun 24, 2026
  48. Derrick StoleeJun 24, 2026
  49. Derrick StoleeJun 24, 2026
  50. Kristofer KarlssonJun 24, 2026
  51. Derrick StoleeJun 24, 2026
  52. 0/8 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jun 26, 2026
  53. 1/8 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jun 26, 2026
  54. 2/8 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jun 26, 2026
  55. 3/8 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jun 26, 2026
  56. 4/8 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Jun 26, 2026
  57. Derrick StoleeJun 26, 2026
  58. Kristofer KarlssonJun 26, 2026
  59. 5/8 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Jun 26, 2026
  60. René ScharfeJun 26, 2026
  61. Kristofer KarlssonJun 26, 2026
  62. 6/8 commit-reach: remove unused nonstale_queue dedup wrappersKristofer Karlsson via GitGitGadget, Jun 26, 2026
  63. 7/8 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jun 26, 2026
  64. Kristofer KarlssonJun 26, 2026
  65. Derrick StoleeJun 26, 2026
  66. Kristofer KarlssonJun 26, 2026
  67. Derrick StoleeJun 26, 2026
  68. Kristofer KarlssonJun 26, 2026
  69. 8/8 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Jun 26, 2026
  70. Derrick StoleeJun 26, 2026
  71. Kristofer KarlssonJun 26, 2026
  72. Derrick StoleeJun 26, 2026
  73. Junio C HamanoJun 26, 2026
  74. Kristofer KarlssonJun 26, 2026
  75. Junio C HamanoJun 26, 2026
  76. 0/8 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jun 28, 2026
  77. 1/8 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jun 28, 2026
  78. 2/8 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jun 28, 2026
  79. 3/8 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jun 28, 2026
  80. 4/8 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Jun 28, 2026
  81. 5/8 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Jun 28, 2026
  82. 6/8 commit-reach: remove unused nonstale_queue dedup wrappersKristofer Karlsson via GitGitGadget, Jun 28, 2026
  83. SZEDER GáborJun 29, 2026
  84. Kristofer KarlssonJun 29, 2026
  85. 7/8 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jun 28, 2026
  86. 8/8 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Jun 28, 2026
  87. Derrick StoleeJun 28, 2026
  88. Derrick StoleeJun 28, 2026
  89. Kristofer KarlssonJun 29, 2026
  90. Derrick StoleeJun 29, 2026
  91. Kristofer KarlssonJun 29, 2026
  92. 00/10 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jul 1, 2026
  93. 01/10 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jul 1, 2026
  94. 02/10 test-lib-functions: improve diagnostic output for trace2 data assertionsKristofer Karlsson via GitGitGadget, Jul 1, 2026
  95. 03/10 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jul 1, 2026
  96. 04/10 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jul 1, 2026
  97. 05/10 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Jul 1, 2026
  98. 06/10 t6600: add clock-skew topologies and step counts for edge casesKristofer Karlsson via GitGitGadget, Jul 1, 2026
  99. 07/10 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Jul 1, 2026
  100. 08/10 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jul 1, 2026
  101. 09/10 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Jul 1, 2026
  102. 10/10 commit-reach: remove commit-date ordering fallbackKristofer Karlsson via GitGitGadget, Jul 1, 2026
  103. Junio C HamanoJul 1, 2026
  104. Kristofer KarlssonJul 1, 2026
  105. Junio C HamanoJul 3, 2026
  106. 00/10 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Jul 11, 2026
  107. 01/10 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Jul 11, 2026
  108. Elijah NewrenJul 26, 2026
  109. Kristofer KarlssonJul 26, 2026
  110. 02/10 test-lib-functions: improve diagnostic output for trace2 data assertionsKristofer Karlsson via GitGitGadget, Jul 11, 2026
  111. René ScharfeJul 25, 2026
  112. Kristofer KarlssonJul 26, 2026
  113. 03/10 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Jul 11, 2026
  114. 04/10 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Jul 11, 2026
  115. 05/10 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Jul 11, 2026
  116. 06/10 t6600: add clock-skew topologies and step counts for edge casesKristofer Karlsson via GitGitGadget, Jul 11, 2026
  117. 07/10 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Jul 11, 2026
  118. 08/10 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Jul 11, 2026
  119. 09/10 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Jul 11, 2026
  120. 10/10 commit-reach: remove commit-date ordering fallbackKristofer Karlsson via GitGitGadget, Jul 11, 2026
  121. Junio C HamanoJul 11, 2026
  122. Kristofer KarlssonJul 11, 2026
  123. Junio C HamanoJul 19, 2026
  124. Kristofer KarlssonJul 21, 2026
  125. Elijah NewrenJul 26, 2026
  126. 00/10 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Aug 6, 2026
  127. 01/10 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Aug 6, 2026
  128. Elijah NewrenAug 7, 2026
  129. 02/10 test-lib-functions: improve diagnostic output for trace2 data assertionsKristofer Karlsson via GitGitGadget, Aug 6, 2026
  130. Elijah NewrenAug 7, 2026
  131. 03/10 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Aug 6, 2026
  132. Elijah NewrenAug 7, 2026
  133. Kristofer KarlssonAug 7, 2026
  134. Elijah NewrenAug 7, 2026
  135. 04/10 t6099, t6600: add side-exhaustion regression testsKristofer Karlsson via GitGitGadget, Aug 6, 2026
  136. Junio C HamanoAug 6, 2026
  137. Kristofer KarlssonAug 6, 2026
  138. Junio C HamanoAug 6, 2026
  139. Elijah NewrenAug 7, 2026
  140. Kristofer KarlssonAug 7, 2026
  141. 05/10 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Aug 6, 2026
  142. Elijah NewrenAug 7, 2026
  143. Kristofer KarlssonAug 7, 2026
  144. Elijah NewrenAug 7, 2026
  145. Kristofer KarlssonAug 7, 2026
  146. 06/10 t6600: add clock-skew topologies and step counts for edge casesKristofer Karlsson via GitGitGadget, Aug 6, 2026
  147. Elijah NewrenAug 7, 2026
  148. 07/10 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Aug 6, 2026
  149. Elijah NewrenAug 7, 2026
  150. Kristofer KarlssonAug 7, 2026
  151. Elijah NewrenAug 7, 2026
  152. Kristofer KarlssonAug 7, 2026
  153. 08/10 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Aug 6, 2026
  154. Elijah NewrenAug 7, 2026
  155. Kristofer KarlssonAug 7, 2026
  156. 09/10 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Aug 6, 2026
  157. 10/10 commit-reach: remove commit-date ordering fallbackKristofer Karlsson via GitGitGadget, Aug 6, 2026
  158. Elijah NewrenAug 7, 2026
  159. Kristofer KarlssonAug 7, 2026
  160. 00/10 commit-reach: terminate merge-base walk when one side is exhaustedKristofer Karlsson via GitGitGadget, Aug 11, 2026
  161. 01/10 Documentation/technical: add paint-down-to-common docKristofer Karlsson via GitGitGadget, Aug 11, 2026
  162. 02/10 test-lib-functions: improve diagnostic output for trace2 data assertionsKristofer Karlsson via GitGitGadget, Aug 11, 2026
  163. 03/10 t6600: add test cases for side-exhaustion edge casesElijah Newren via GitGitGadget, Aug 11, 2026
  164. 04/10 t6099: add side-exhaustion regression testKristofer Karlsson via GitGitGadget, Aug 11, 2026
  165. 05/10 commit-reach: add trace2 instrumentation to paint_down_to_common()Kristofer Karlsson via GitGitGadget, Aug 11, 2026
  166. 06/10 t6600: add clock-skew topologies and step counts for edge casesKristofer Karlsson via GitGitGadget, Aug 11, 2026
  167. 07/10 commit-reach: introduce struct paint_state with per-side countersKristofer Karlsson via GitGitGadget, Aug 11, 2026
  168. 08/10 commit-reach: terminate merge-base walk when one paint side is exhaustedKristofer Karlsson via GitGitGadget, Aug 11, 2026
  169. 09/10 commit-reach: move min_generation check into paint_queue_get()Kristofer Karlsson via GitGitGadget, Aug 11, 2026
  170. 10/10 commit-reach: remove commit-date ordering fallbackKristofer Karlsson via GitGitGadget, Aug 11, 2026
  171. Elijah NewrenAug 12, 2026
  172. Kristofer KarlssonAug 12, 2026
  173. Junio C HamanoAug 12, 2026
  174. Kristofer KarlssonAug 12, 2026
  175. Elijah NewrenAug 12, 2026
  176. Junio C HamanoAug 12, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.