]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/repack.c: remove redundant pack-based bitmaps
authorTaylor Blau <me@ttaylorr.com>
Tue, 18 Oct 2022 02:45:12 +0000 (22:45 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Oct 2022 04:26:16 +0000 (21:26 -0700)
When we write a MIDX bitmap after repacking, it is possible that the
repository would be left in a state with both pack- and multi-pack
reachability bitmaps.

This can occur, for instance, if a pack that was kept (either by having
a .keep file, or during a geometric repack in which it is not rolled up)
has a bitmap file, and the repack wrote a multi-pack index and bitmap.

When loading a reachability bitmap for the repository, the multi-pack
one is always preferred, so the pack-based one is redundant. Let's
remove it unconditionally, even if '-d' isn't passed, since there is no
practical reason to keep both around. The patch below does just that.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/repack.c
t/t7700-repack.sh

index a5bacc7797435696cd6e23e73f847fc00d39bb7f..c2d2e52bd462ce873c888611a719e02ee203da58 100644 (file)
@@ -661,6 +661,35 @@ static int write_midx_included_packs(struct string_list *include,
        return finish_command(&cmd);
 }
 
+static void remove_redundant_bitmaps(struct string_list *include,
+                                    const char *packdir)
+{
+       struct strbuf path = STRBUF_INIT;
+       struct string_list_item *item;
+       size_t packdir_len;
+
+       strbuf_addstr(&path, packdir);
+       strbuf_addch(&path, '/');
+       packdir_len = path.len;
+
+       /*
+        * Remove any pack bitmaps corresponding to packs which are now
+        * included in the MIDX.
+        */
+       for_each_string_list_item(item, include) {
+               strbuf_addstr(&path, item->string);
+               strbuf_strip_suffix(&path, ".idx");
+               strbuf_addstr(&path, ".bitmap");
+
+               if (unlink(path.buf) && errno != ENOENT)
+                       warning_errno(_("could not remove stale bitmap: %s"),
+                                     path.buf);
+
+               strbuf_setlen(&path, packdir_len);
+       }
+       strbuf_release(&path);
+}
+
 static int write_cruft_pack(const struct pack_objects_args *args,
                            const char *pack_prefix,
                            struct string_list *names,
@@ -1059,6 +1088,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                                                refs_snapshot ? get_tempfile_path(refs_snapshot) : NULL,
                                                show_progress, write_bitmaps > 0);
 
+               if (!ret && write_bitmaps)
+                       remove_redundant_bitmaps(&include, packdir);
+
                string_list_clear(&include, 0);
 
                if (ret)
index ca45c4cd2c1a8a422e396fd4d29dee8c49c0c10e..2d0e9448ddc6347a249529d28786e2ba73072484 100755 (executable)
@@ -426,6 +426,27 @@ test_expect_success '--write-midx -b packs non-kept objects' '
        )
 '
 
+test_expect_success '--write-midx removes stale pack-based bitmaps' '
+       rm -fr repo &&
+       git init repo &&
+       test_when_finished "rm -fr repo" &&
+       (
+               cd repo &&
+               test_commit base &&
+               GIT_TEST_MULTI_PACK_INDEX=0 git repack -Ab &&
+
+               pack_bitmap=$(ls $objdir/pack/pack-*.bitmap) &&
+               test_path_is_file "$pack_bitmap" &&
+
+               test_commit tip &&
+               GIT_TEST_MULTI_PACK_INDEX=0 git repack -bm &&
+
+               test_path_is_file $midx &&
+               test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+               test_path_is_missing $pack_bitmap
+       )
+'
+
 test_expect_success TTY '--quiet disables progress' '
        test_terminal env GIT_PROGRESS_DELAY=0 \
                git -C midx repack -ad --quiet --write-midx 2>stderr &&