]> git.ipfire.org Git - thirdparty/git.git/commitdiff
t6600: add test for merge-base early exit with clock skew
authorKristofer Karlsson <krka@spotify.com>
Mon, 29 Jun 2026 13:19:20 +0000 (13:19 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 29 Jun 2026 17:40:35 +0000 (10:40 -0700)
Add a topology where the correct merge base (M2) has a lower
committer date than its ancestor (M1) due to clock skew.  With a
v1 commit graph (topological levels only, no corrected commit
dates), paint_down_to_common() falls back to commit-date ordering.
In that mode, M1 pops before M2, acquires both paint sides, and
the !FIND_ALL early exit fires -- returning the wrong merge base.

Mark the test as test_expect_failure to document the bug; the next
commit will fix it.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t6600-test-reach.sh

index 51c23b76833126d697d8c3ecde0e8b8ed9ebe8be..601656fda655944fda394de8683439d518f2c958 100755 (executable)
@@ -49,6 +49,42 @@ test_expect_success 'setup' '
                        git tag -a -m "$x-$i" tag-$x-$i commit-$x-$i || return 1
                done
        done &&
+       # Build a topology with clock skew to test the !FIND_ALL early
+       # exit in paint_down_to_common().  M2 is the correct merge base
+       # of P1 and P2, but its ancestor M1 has a higher committer date
+       # due to clock skew.  With date-only ordering (v1 commit graph
+       # without corrected commit dates), M1 pops from the queue first,
+       # gets both paint sides, and the early exit fires before M2 is
+       # ever visited.
+       #
+       #        P1     P2          @7000
+       #        |     /  \
+       #        A    B    D        @6000
+       #       / \   |    |
+       #      |  M2--+    |        @2000 (correct merge base)
+       #       \ |        |
+       #        M1--------+        @5000 (clock skew: date > M2)
+       #        |
+       #       root                @1000
+       #
+       git checkout --orphan skew-orphan &&
+       skew_tree=$(git mktree </dev/null) &&
+       skew_commit () {
+               GIT_COMMITTER_DATE="@$1 +0000" GIT_AUTHOR_DATE="@$1 +0000" \
+                       git commit-tree -m "$2" "$skew_tree" $3 $4 $5 $6
+       } &&
+       skew_root=$(skew_commit 1000 root) &&
+       skew_M1=$(skew_commit 5000 M1 -p "$skew_root") &&
+       skew_M2=$(skew_commit 2000 M2 -p "$skew_M1") &&
+       skew_A=$(skew_commit 6000 A -p "$skew_M1" -p "$skew_M2") &&
+       skew_B=$(skew_commit 6000 B -p "$skew_M2") &&
+       skew_D=$(skew_commit 6000 D -p "$skew_M1") &&
+       skew_P1=$(skew_commit 7000 P1 -p "$skew_A") &&
+       skew_P2=$(skew_commit 7000 P2 -p "$skew_B" -p "$skew_D") &&
+       git branch -f skew-P1 "$skew_P1" &&
+       git branch -f skew-P2 "$skew_P2" &&
+       git tag skew-M2 "$skew_M2" &&
+
        git commit-graph write --reachable &&
        mv .git/objects/info/commit-graph commit-graph-full &&
        chmod u+w commit-graph-full &&
@@ -922,4 +958,9 @@ test_expect_success 'merge-base without --all is one of --all results' '
        grep -F -f single all
 '
 
+test_expect_failure 'merge-base without --all, clock skew, v1 commit-graph' '
+       git rev-parse skew-M2 >expect &&
+       merge_base_all_modes skew-P1 skew-P2
+'
+
 test_done