Skip to content

Commit a72dfab

Browse files
ttaylorrgitster
authored andcommitted
pseudo-merge.c: ensure pseudo-merge groups are closed
When generating pseudo-merge bitmaps, it's possible that concurrent reference updates may reveal some pseudo-merge candidates which reach objects that are not contained in the bitmap's pack or pseudo-pack order (in the case of MIDX bitmaps). The latter case is relatively easy to demonstrate: if we generate a MIDX bitmap with only half of the repository packed, then the unpacked contents are not part of the MIDX's object order. If we happen to select one or more commit(s) from the unpacked portion of the repository for inclusion in a pseudo-merge, we'll get the following message when trying to generate its bitmap: $ git multi-pack-index write --bitmap [...] Selecting pseudo-merge commits: 100% (1/1), done. warning: Failed to write bitmap index. Packfile doesn't have full closure (object ... is missing) Building bitmaps: 50% (1/2), done. error: could not write multi-pack bitmap , and the attempted bitmap write will fail, leaving the repository without a current bitmap. Rectify this by ensuring that the commits which are pseudo-merge candidates can only be so if they appear somewhere in the packing order. This is sufficient, since we know that the original packing order is closed under reachability, so if a commit appears in that list as a potential pseudo-merge candidate, we know that everything reachable from it also appears in the list (and thus the candidate is a good one). Noticed-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 25b7866 commit a72dfab

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

pseudo-merge.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ static int find_pseudo_merge_group_for_ref(const char *refname,
217217
c = lookup_commit(the_repository, oid);
218218
if (!c)
219219
return 0;
220+
if (!packlist_find(writer->to_pack, oid))
221+
return 0;
220222

221223
has_bitmap = bitmap_writer_has_bitmapped_object_id(writer, oid);
222224

t/t5333-pseudo-merge-bitmaps.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,40 @@ test_expect_success 'empty pseudo-merge group' '
410410
)
411411
'
412412

413+
test_expect_success 'pseudo-merge closure' '
414+
git init pseudo-merge-closure &&
415+
(
416+
cd pseudo-merge-closure &&
417+
418+
test_commit A &&
419+
git repack -d &&
420+
421+
test_commit B &&
422+
423+
# Note that the contents of A is packed, but B is not. A
424+
# (and the objects reachable from it) are thus visible
425+
# to the MIDX, but the same is not true for B and its
426+
# objects.
427+
#
428+
# Ensure that we do not attempt to create a pseudo-merge
429+
# for B, depsite it matching the below pseudo-merge
430+
# group pattern, as doing so would result in a failure
431+
# to write a non-closed bitmap.
432+
git config bitmapPseudoMerge.test.pattern refs/ &&
433+
git config bitmapPseudoMerge.test.threshold now &&
434+
435+
git multi-pack-index write --bitmap &&
436+
437+
test-tool bitmap dump-pseudo-merges >pseudo-merges &&
438+
test_line_count = 1 pseudo-merges &&
439+
440+
git rev-parse A >expect &&
441+
442+
test-tool bitmap list-commits >actual &&
443+
test_cmp expect actual &&
444+
test-tool bitmap dump-pseudo-merge-commits 0 >actual &&
445+
test_cmp expect actual
446+
)
447+
'
448+
413449
test_done

0 commit comments

Comments
 (0)