t5333: demonstrate various pseudo-merge bugs
Using the test helper introduced via the previous commit, add various failing tests demonstrating bugs in the pseudo-merge implementation. These are all marked as failing with one exception. The "sampleRate=0" test describes a latent bug, which is only reachable through a code path that is itself masked by a separate bug. A future commit will fix that bug, and, in turn, cause the aforementioned test to fail. Accordingly, that commit will mark the test as failing, and it will be re-marked as passing in a separate commit which fixes the once-latent bug. For the rest: the following commits will explain and fix the underlying bugs in detail. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
May 11, 2026 at 20:46 UTC
49369d8290c3a5c95d835df85fdf53eba7562496
1 file changed
+198
t/t5333-pseudo-merge-bitmaps.sh
+198
@@ -462,4 +462,202 @@ test_expect_success 'use pseudo-merge in boundary traversal' '
462
)
463
'
464
465
+test_expect_failure 'apply pseudo-merges during fill-in traversal' '
466
+ test_when_finished "rm -fr pseudo-merge-fill-in-traversal" &&
467
+ git init pseudo-merge-fill-in-traversal &&
468
+ (
469
+ cd pseudo-merge-fill-in-traversal &&
470
+
471
+ git config bitmapPseudoMerge.test.pattern refs/tags/ &&
472
+ git config bitmapPseudoMerge.test.maxMerges 1 &&
473
+ git config bitmapPseudoMerge.test.stableThreshold never &&
474
+
475
+ test_commit_bulk 64 &&
476
+ tag_everything &&
477
+ git repack -ad &&
478
+
479
+ pack=$(ls .git/objects/pack/pack-*.pack) &&
480
+ git rev-parse HEAD~63 >in &&
481
+ test-tool bitmap write "$(basename $pack)" <in &&
482
+
483
+ test_pseudo_merges >merges &&
484
+ test_line_count = 1 merges &&
485
+
486
+ test_commit stale &&
487
+
488
+ git rev-list --count --objects HEAD >expect &&
489
+
490
+ : >trace2.txt &&
491
+ GIT_TRACE2_EVENT=$PWD/trace2.txt \
492
+ git rev-list --count --objects --use-bitmap-index HEAD >actual &&
493
+ test_pseudo_merges_satisfied 1 <trace2.txt &&
494
+
495
+ test_cmp expect actual
496
+ )
497
+'
498
+
499
+test_expect_failure 'apply pseudo-merges from multiple groups during fill-in' '
500
+ test_when_finished "rm -fr pseudo-merge-fill-in-multi" &&
501
+ git init pseudo-merge-fill-in-multi &&
502
+ (
503
+ cd pseudo-merge-fill-in-multi &&
504
+
505
+ test_commit base &&
506
+ base=$(git rev-parse HEAD) &&
507
+
508
+ for side in left right
509
+ do
510
+ git checkout -B $side base &&
511
+
512
+ test_commit_bulk --id=$side 64 &&
513
+ git rev-list --no-object-names HEAD --not $base >in &&
514
+ while read oid
515
+ do
516
+ echo "create refs/group-$side/$oid $oid" || return 1
517
+ done <in | git update-ref --stdin || return 1
518
+ done &&
519
+
520
+ git checkout left &&
521
+ git merge right &&
522
+ git repack -ad &&
523
+
524
+ git config bitmapPseudoMerge.left.pattern "refs/group-left/" &&
525
+ git config bitmapPseudoMerge.left.maxMerges 1 &&
526
+ git config bitmapPseudoMerge.left.stableThreshold never &&
527
+
528
+ git config bitmapPseudoMerge.right.pattern "refs/group-right/" &&
529
+ git config bitmapPseudoMerge.right.maxMerges 1 &&
530
+ git config bitmapPseudoMerge.right.stableThreshold never &&
531
+
532
+ pack="$(ls .git/objects/pack/pack-*.pack)" &&
533
+ git rev-parse "$base" >in &&
534
+ test-tool bitmap write "$(basename $pack)" <in &&
535
+
536
+ test_pseudo_merges >merges &&
537
+ test_line_count = 2 merges &&
538
+
539
+ test_commit stale &&
540
+
541
+ git rev-list --count --objects HEAD >expect &&
542
+
543
+ : >trace2.txt &&
544
+ GIT_TRACE2_EVENT=$PWD/trace2.txt \
545
+ git rev-list --count --objects --use-bitmap-index HEAD >actual &&
546
+ test_pseudo_merges_satisfied 2 <trace2.txt &&
547
+
548
+ test_cmp expect actual
549
+ )
550
+'
551
+
552
+test_expect_failure 'apply pseudo-merges with overlapping groups during fill-in' '
553
+ test_when_finished "rm -fr pseudo-merge-fill-in-overlap" &&
554
+ git init pseudo-merge-fill-in-overlap &&
555
+ (
556
+ cd pseudo-merge-fill-in-overlap &&
557
+
558
+ test_commit_bulk 64 &&
559
+ tag_everything &&
560
+ git repack -ad &&
561
+
562
+ pack="$(ls .git/objects/pack/pack-*.pack)" &&
563
+
564
+ # Use two pseudo-merge group patterns that both match
565
+ # refs/tags/, so every tagged commit belongs to both
566
+ # groups. This exercises the extended lookup table
567
+ # path in apply_pseudo_merges_for_commit().
568
+ git config bitmapPseudoMerge.all.pattern "refs/tags/" &&
569
+ git config bitmapPseudoMerge.all.maxMerges 1 &&
570
+ git config bitmapPseudoMerge.all.stableThreshold never &&
571
+
572
+ git config bitmapPseudoMerge.tags.pattern "refs/tags/" &&
573
+ git config bitmapPseudoMerge.tags.maxMerges 1 &&
574
+ git config bitmapPseudoMerge.tags.stableThreshold never &&
575
+
576
+ git rev-parse HEAD~63 >in &&
577
+ test-tool bitmap write "$(basename $pack)" <in &&
578
+
579
+ test_pseudo_merges >merges &&
580
+ test_line_count = 2 merges &&
581
+
582
+ test_commit stale &&
583
+
584
+ git rev-list --count --objects HEAD >expect &&
585
+
586
+ : >trace2.txt &&
587
+ GIT_TRACE2_EVENT=$PWD/trace2.txt \
588
+ git rev-list --count --objects --use-bitmap-index HEAD >actual &&
589
+ test_pseudo_merges_satisfied 2 <trace2.txt &&
590
+
591
+ test_cmp expect actual
592
+ )
593
+'
594
+
595
+test_expect_failure 'pseudo-merge commits are correctly classified by date' '
596
+ test_when_finished "rm -fr pseudo-merge-date-classification" &&
597
+ git init pseudo-merge-date-classification &&
598
+ (
599
+ cd pseudo-merge-date-classification &&
600
+
601
+ test_commit_bulk 64 &&
602
+ tag_everything &&
603
+ git repack -ad &&
604
+
605
+ pack="$(ls .git/objects/pack/pack-*.pack)" &&
606
+
607
+ # Configure two pseudo-merge groups: one that only
608
+ # matches "stable" refs (older than one month), and one
609
+ # that matches all refs. With 64 freshly-created tags
610
+ # (all younger than one month) the stable group should
611
+ # have zero pseudo-merges and the catch-all group should
612
+ # have one.
613
+ #
614
+ # Use GIT_TEST_DATE_NOW to align "now" (and therefore
615
+ # "1.month.ago") with the test_tick timestamps so that
616
+ # the commits are within the last month.
617
+ #
618
+ # This exercises the date-based classification in
619
+ # find_pseudo_merge_group_for_ref(), which requires
620
+ # that commits are parsed before inspecting their date.
621
+ git config bitmapPseudoMerge.stable.pattern "refs/tags/" &&
622
+ git config bitmapPseudoMerge.stable.maxMerges 64 &&
623
+ git config bitmapPseudoMerge.stable.stableThreshold never &&
624
+ git config bitmapPseudoMerge.stable.threshold 1.month.ago &&
625
+
626
+ git config bitmapPseudoMerge.all.pattern "refs/tags/" &&
627
+ git config bitmapPseudoMerge.all.maxMerges 1 &&
628
+ git config bitmapPseudoMerge.all.stableThreshold never &&
629
+ git config bitmapPseudoMerge.all.threshold now &&
630
+
631
+ git rev-parse HEAD~63 >in &&
632
+ GIT_TEST_DATE_NOW=$test_tick \
633
+ test-tool bitmap write "$(basename $pack)" <in &&
634
+
635
+ test_pseudo_merges >merges &&
636
+ test_line_count = 1 merges
637
+ )
638
+'
639
+
640
+test_expect_success 'sampleRate=0 does not cause division by zero' '
641
+ test_when_finished "rm -fr pseudo-merge-sample-rate-zero" &&
642
+ git init pseudo-merge-sample-rate-zero &&
643
+ (
644
+ cd pseudo-merge-sample-rate-zero &&
645
+
646
+ test_commit_bulk 64 &&
647
+ tag_everything &&
648
+ git repack -ad &&
649
+
650
+ pack="$(ls .git/objects/pack/pack-*.pack)" &&
651
+
652
+ git config bitmapPseudoMerge.test.pattern "refs/tags/" &&
653
+ git config bitmapPseudoMerge.test.maxMerges 1 &&
654
+ git config bitmapPseudoMerge.test.sampleRate 0 &&
655
+ git config bitmapPseudoMerge.test.threshold now &&
656
+ git config bitmapPseudoMerge.test.stableThreshold never &&
657
+
658
+ git rev-parse HEAD~63 >in &&
659
+ test-tool bitmap write "$(basename $pack)" <in
660
+ )
661
+'
662
+
663
test_done