]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pack-bitmap: fix inverted binary search in `pseudo_merge_at()`
authorTaylor Blau <me@ttaylorr.com>
Tue, 12 May 2026 00:46:57 +0000 (20:46 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 12 May 2026 01:36:18 +0000 (10:36 +0900)
The binary search in `pseudo_merge_at()` has its "lo" and "hi" updates
swapped: when the midpoint's offset is less than the target, it sets `hi
= mi` (searching left) instead of `lo = mi + 1` (searching right), and
vice versa.

This means that lookups for pseudo-merges whose offset is not near the
midpoint of the pseudo-merge table are likely to fail.

In practice, with a single pseudo-merge group this is masked because the
lone entry is always at the midpoint. With multiple groups, the inverted
comparisons cause lookups to search in the wrong direction, potentially
missing entries.

Swap the "lo" and "hi" assignments to search in the correct direction,
making it possible to apply pseudo-merges during fill-in when more than
one pseudo-merge exists in a group.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pseudo-merge.c
t/t5333-pseudo-merge-bitmaps.sh

index ff18b6c364245ea90a4ab48e676a1213bdfac7f0..fb71c7617924a795853b8cc64239af239202051b 100644 (file)
@@ -559,9 +559,9 @@ static struct pseudo_merge *pseudo_merge_at(const struct pseudo_merge_map *pm,
                if (got == want)
                        return use_pseudo_merge(pm, &pm->v[mi]);
                else if (got < want)
-                       hi = mi;
-               else
                        lo = mi + 1;
+               else
+                       hi = mi;
        }
 
        warning(_("could not find pseudo-merge for commit %s at offset %"PRIuMAX),
index 3d7a7668121f493c73b4a6da00b5fe42d16b81d7..5411fbf1e0451681b105002c6d16f7f8789c951a 100755 (executable)
@@ -496,7 +496,7 @@ test_expect_success 'apply pseudo-merges during fill-in traversal' '
        )
 '
 
-test_expect_failure 'apply pseudo-merges from multiple groups during fill-in' '
+test_expect_success 'apply pseudo-merges from multiple groups during fill-in' '
        test_when_finished "rm -fr pseudo-merge-fill-in-multi" &&
        git init pseudo-merge-fill-in-multi &&
        (