From: "Kristofer Karlsson via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Derrick Stolee <stolee@gmail.com>,
Elijah Newren <newren@gmail.com>,
Kristofer Karlsson <krka@spotify.com>,
Kristofer Karlsson <krka@spotify.com>
Subject: [PATCH v4 3/8] t6099, t6600: add side-exhaustion regression tests
Date: Sun, 28 Jun 2026 12:25:41 +0000 [thread overview]
Message-ID: <017bf156c57ceb2df33b316d4537baf3a72672fd.1782649547.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2149.v4.git.1782649547.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
Add t6099 to test the case where multiple merge-base candidates exist
and one is an ancestor of another. This exercises the side-exhaustion
optimization in paint_down_to_common together with the
remove_redundant safety net in get_merge_bases_many_0.
Add a mixed finite/INFINITY test to t6600 where one tip is outside
the commit-graph (INFINITY generation) and the other is inside.
This exercises the region transition: the walk starts in the
INFINITY region where side-exhaustion is disabled, then crosses
into the finite region where it can fire.
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
t/meson.build | 1 +
t/t6099-merge-base-side-exhaustion.sh | 82 +++++++++++++++++++++++++++
t/t6600-test-reach.sh | 25 ++++++++
3 files changed, 108 insertions(+)
create mode 100755 t/t6099-merge-base-side-exhaustion.sh
diff --git a/t/meson.build b/t/meson.build
index 3219264fe7..ee6ebdffb9 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -786,6 +786,7 @@ integration_tests = [
't6041-bisect-submodule.sh',
't6050-replace.sh',
't6060-merge-index.sh',
+ 't6099-merge-base-side-exhaustion.sh',
't6100-rev-list-in-order.sh',
't6101-rev-parse-parents.sh',
't6102-rev-list-unexpected-objects.sh',
diff --git a/t/t6099-merge-base-side-exhaustion.sh b/t/t6099-merge-base-side-exhaustion.sh
new file mode 100755
index 0000000000..4f1e0d50ef
--- /dev/null
+++ b/t/t6099-merge-base-side-exhaustion.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+test_description='merge-base with ancestor among merge-base candidates
+
+Test that merge-base --all correctly handles cases where
+multiple merge-base candidates exist and one is an ancestor
+of another. The side-exhaustion optimization in
+paint_down_to_common may exit before STALE propagation
+removes the ancestor, but remove_redundant catches it.
+
+Graph shape (parents are below children):
+
+ A ----------- X
+ |\ /|
+ | B---------/ |
+ | | |
+ e2 \ f2
+ | | |
+ e1 d1 f1
+ \ | /
+ \ | /
+ \| /
+ C
+
+A and X are the two tips.
+B and C are both reachable from A and X.
+B reaches C through d1.
+Only B should appear in merge-base --all output.
+'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+test_expect_success 'setup ancestor merge-base candidate' '
+ test_commit C &&
+
+ git checkout -b d-chain HEAD &&
+ test_commit d1 &&
+ test_commit B &&
+
+ git checkout -b e-path C &&
+ test_commit e1 &&
+ test_commit e2 &&
+
+ git checkout -b f-path C &&
+ test_commit f1 &&
+ test_commit f2 &&
+
+ git checkout -b branch-A e-path &&
+ test_merge A B &&
+
+ git checkout -b branch-X f-path &&
+ test_merge X B &&
+
+ git commit-graph write --reachable
+'
+
+test_expect_success 'merge-base --all excludes ancestor candidate' '
+ git rev-parse B >expected &&
+ git merge-base --all A X >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'merge-base (single) finds shallowest' '
+ git rev-parse B >expected &&
+ git merge-base A X >actual &&
+ test_cmp expected actual
+'
+
+# Without commit-graph: generation numbers are INFINITY,
+# side-exhaustion optimization does not fire.
+test_expect_success 'merge-base --all without commit-graph' '
+ rm -f .git/objects/info/commit-graph &&
+ git rev-parse B >expected &&
+ git merge-base --all A X >actual &&
+ test_cmp expected actual
+'
+
+test_done
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index c2e091aad1..4b771b4c58 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -294,6 +294,31 @@ test_expect_success 'get_merge_bases_many:infinity-both-sides' '
test_all_modes get_merge_bases_many
'
+test_expect_success 'setup mixed finite/INFINITY topology' '
+ # Create a commit outside all saved commit-graph files so it always
+ # has INFINITY generation, while its parent (ps-X) is in the graph
+ # with a finite generation. Use the ps-* orphan topology so we do
+ # not pollute the grid-based rev-list tests.
+ git checkout ps-X &&
+ test_env GIT_TEST_COMMIT_GRAPH= test_commit pm-INF
+'
+
+test_expect_success 'get_merge_bases_many:mixed-finite-infinity' '
+ # One tip (pm-INF) is outside the commit-graph with INFINITY
+ # generation; the other (ps-B) is in the graph with finite
+ # generation. The walk starts in the INFINITY region and crosses
+ # into the finite region where side-exhaustion can fire.
+ cat >input <<-\EOF &&
+ A:pm-INF
+ X:ps-B
+ EOF
+ {
+ echo "get_merge_bases_many(A,X):" &&
+ git rev-parse ps-X
+ } >expect &&
+ test_all_modes get_merge_bases_many
+'
+
test_expect_success 'reduce_heads' '
cat >input <<-\EOF &&
X:commit-1-10
--
gitgitgadget
next prev parent reply other threads:[~2026-06-28 12:25 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-20 10:36 [PATCH/RFC 0/6] commit-reach: terminate merge-base walk when one side is exhausted Kristofer Karlsson via GitGitGadget
2026-06-20 10:36 ` [PATCH/RFC 1/6] commit-reach: decouple ahead_behind from nonstale_queue Kristofer Karlsson via GitGitGadget
2026-06-22 18:00 ` Derrick Stolee
2026-06-22 18:53 ` Kristofer Karlsson
2026-06-20 10:36 ` [PATCH/RFC 2/6] commit-reach: introduce struct paint_queue with per-side counters Kristofer Karlsson via GitGitGadget
2026-06-22 18:10 ` Derrick Stolee
2026-06-22 19:14 ` Kristofer Karlsson
2026-06-22 20:23 ` Derrick Stolee
2026-06-23 10:13 ` Kristofer Karlsson
2026-06-23 13:50 ` Derrick Stolee
2026-06-23 14:09 ` Kristofer Karlsson
2026-06-23 14:17 ` Derrick Stolee
2026-06-24 11:25 ` Kristofer Karlsson
2026-06-20 10:36 ` [PATCH/RFC 3/6] commit-reach: terminate merge-base walk when one paint side is exhausted Kristofer Karlsson via GitGitGadget
2026-06-22 18:12 ` Derrick Stolee
2026-06-22 19:19 ` Kristofer Karlsson
2026-06-22 20:26 ` Derrick Stolee
2026-06-22 21:03 ` Kristofer Karlsson
2026-06-23 13:40 ` Derrick Stolee
2026-06-20 10:36 ` [PATCH/RFC 4/6] t6600: add test cases for side-exhaustion edge cases Elijah Newren via GitGitGadget
2026-06-22 18:15 ` Derrick Stolee
2026-06-22 19:25 ` Kristofer Karlsson
2026-06-22 20:28 ` Derrick Stolee
2026-06-20 10:36 ` [PATCH/RFC 5/6] t6099, t6600: add side-exhaustion regression tests Kristofer Karlsson via GitGitGadget
2026-06-22 18:16 ` Derrick Stolee
2026-06-20 10:36 ` [PATCH/RFC 6/6] Documentation/technical: add paint-down-to-common doc Kristofer Karlsson via GitGitGadget
2026-06-22 18:21 ` Derrick Stolee
2026-06-22 19:30 ` Kristofer Karlsson
2026-06-22 18:22 ` [PATCH/RFC 0/6] commit-reach: terminate merge-base walk when one side is exhausted Derrick Stolee
2026-06-24 12:14 ` [PATCH v2 0/7] " Kristofer Karlsson via GitGitGadget
2026-06-24 12:14 ` [PATCH v2 1/7] Documentation/technical: add paint-down-to-common doc Kristofer Karlsson via GitGitGadget
2026-06-24 17:09 ` Junio C Hamano
2026-06-24 12:14 ` [PATCH v2 2/7] t6600: add test cases for side-exhaustion edge cases Elijah Newren via GitGitGadget
2026-06-24 13:43 ` Derrick Stolee
2026-06-24 14:33 ` Kristofer Karlsson
2026-06-24 12:14 ` [PATCH v2 3/7] t6099, t6600: add side-exhaustion regression tests Kristofer Karlsson via GitGitGadget
2026-06-24 12:14 ` [PATCH v2 4/7] commit-reach: add trace2 instrumentation to paint_down_to_common() Kristofer Karlsson via GitGitGadget
2026-06-24 13:41 ` Derrick Stolee
2026-06-24 14:31 ` Kristofer Karlsson
2026-06-24 12:14 ` [PATCH v2 5/7] commit-reach: introduce struct paint_state with per-side counters Kristofer Karlsson via GitGitGadget
2026-06-24 13:54 ` Derrick Stolee
2026-06-24 14:38 ` Kristofer Karlsson
2026-06-24 12:14 ` [PATCH v2 6/7] commit-reach: remove unused nonstale_queue dedup wrappers Kristofer Karlsson via GitGitGadget
2026-06-24 13:55 ` Derrick Stolee
2026-06-24 12:14 ` [PATCH v2 7/7] commit-reach: terminate merge-base walk when one paint side is exhausted Kristofer Karlsson via GitGitGadget
2026-06-24 14:02 ` Derrick Stolee
2026-06-24 14:47 ` Kristofer Karlsson
2026-06-24 15:07 ` Derrick Stolee
2026-06-24 13:34 ` [PATCH v2 0/7] commit-reach: terminate merge-base walk when one " Derrick Stolee
2026-06-24 14:25 ` Kristofer Karlsson
2026-06-24 14:09 ` Derrick Stolee
2026-06-26 13:07 ` [PATCH v3 0/8] " Kristofer Karlsson via GitGitGadget
2026-06-26 13:07 ` [PATCH v3 1/8] Documentation/technical: add paint-down-to-common doc Kristofer Karlsson via GitGitGadget
2026-06-26 13:07 ` [PATCH v3 2/8] t6600: add test cases for side-exhaustion edge cases Elijah Newren via GitGitGadget
2026-06-26 13:08 ` [PATCH v3 3/8] t6099, t6600: add side-exhaustion regression tests Kristofer Karlsson via GitGitGadget
2026-06-26 13:08 ` [PATCH v3 4/8] commit-reach: add trace2 instrumentation to paint_down_to_common() Kristofer Karlsson via GitGitGadget
2026-06-26 14:31 ` Derrick Stolee
2026-06-26 14:35 ` Kristofer Karlsson
2026-06-26 13:08 ` [PATCH v3 5/8] commit-reach: introduce struct paint_state with per-side counters Kristofer Karlsson via GitGitGadget
2026-06-26 21:13 ` René Scharfe
2026-06-26 21:57 ` Kristofer Karlsson
2026-06-26 13:08 ` [PATCH v3 6/8] commit-reach: remove unused nonstale_queue dedup wrappers Kristofer Karlsson via GitGitGadget
2026-06-26 13:08 ` [PATCH v3 7/8] commit-reach: terminate merge-base walk when one paint side is exhausted Kristofer Karlsson via GitGitGadget
2026-06-26 14:29 ` Kristofer Karlsson
2026-06-26 14:32 ` Derrick Stolee
2026-06-26 16:41 ` Kristofer Karlsson
2026-06-26 14:35 ` Derrick Stolee
2026-06-26 14:39 ` Kristofer Karlsson
2026-06-26 13:08 ` [PATCH v3 8/8] commit-reach: move min_generation check into paint_queue_get() Kristofer Karlsson via GitGitGadget
2026-06-26 14:42 ` Derrick Stolee
2026-06-26 14:53 ` Kristofer Karlsson
2026-06-26 14:58 ` Derrick Stolee
2026-06-26 16:36 ` [PATCH v3 0/8] commit-reach: terminate merge-base walk when one side is exhausted Junio C Hamano
2026-06-26 16:43 ` Kristofer Karlsson
2026-06-26 18:43 ` Junio C Hamano
2026-06-28 12:25 ` [PATCH v4 " Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 1/8] Documentation/technical: add paint-down-to-common doc Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 2/8] t6600: add test cases for side-exhaustion edge cases Elijah Newren via GitGitGadget
2026-06-28 12:25 ` Kristofer Karlsson via GitGitGadget [this message]
2026-06-28 12:25 ` [PATCH v4 4/8] commit-reach: add trace2 instrumentation to paint_down_to_common() Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 5/8] commit-reach: introduce struct paint_state with per-side counters Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 6/8] commit-reach: remove unused nonstale_queue dedup wrappers Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 7/8] commit-reach: terminate merge-base walk when one paint side is exhausted Kristofer Karlsson via GitGitGadget
2026-06-28 12:25 ` [PATCH v4 8/8] commit-reach: move min_generation check into paint_queue_get() Kristofer Karlsson via GitGitGadget
2026-06-28 15:15 ` Derrick Stolee
2026-06-28 15:16 ` [PATCH v4 0/8] commit-reach: terminate merge-base walk when one side is exhausted Derrick Stolee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=017bf156c57ceb2df33b316d4537baf3a72672fd.1782649547.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=krka@spotify.com \
--cc=newren@gmail.com \
--cc=stolee@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.