@matheusbsbs / matheus-bagliano / commits / e08f7bb093
Fork 0

builtin/repack.c: invalidate MIDX only when necessary

In 525e18c04b (midx: clear midx on repack, 2018-07-12), 'git repack' learned to remove a multi-pack-index file if it added or removed a pack from the object store. This mechanism is a little over-eager, since it is only necessary to drop a MIDX if 'git repack' removes a pack that the MIDX references. Adding a pack outside of the MIDX does not require invalidating the MIDX, and likewise for removing a pack the MIDX does not know about. Teach 'git repack' to check for this by loading the MIDX, and checking whether the to-be-removed pack is known to the MIDX. This requires a slightly odd alternation to a test in t5319, which is explained with a comment. A new test is added to show that the MIDX is left alone when both packs known to it are marked as .keep, but two packs unknown to it are removed and combined into one new pack. Helped-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Aug 25, 2020 at 12:04 UTC e08f7bb09369d739ef03e1ac0180140a68e70982
2 files changed +47 -9
builtin/repack.c
+5 -7
@@ -133,7 +133,11 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
133 static void remove_redundant_pack(const char *dir_name, const char *base_name)
134 {
135 struct strbuf buf = STRBUF_INIT;
136 - strbuf_addf(&buf, "%s/%s.pack", dir_name, base_name);
136 + struct multi_pack_index *m = get_multi_pack_index(the_repository);
137 + strbuf_addf(&buf, "%s.pack", base_name);
138 + if (m && midx_contains_pack(m, buf.buf))
139 + clear_midx_file(the_repository);
140 + strbuf_insertf(&buf, 0, "%s/", dir_name);
141 unlink_pack_path(buf.buf, 1);
142 strbuf_release(&buf);
143 }
@@ -286,7 +290,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
290 int keep_unreachable = 0;
291 struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
292 int no_update_server_info = 0;
289 - int midx_cleared = 0;
293 struct pack_objects_args po_args = {NULL};
294
295 struct option builtin_repack_options[] = {
@@ -439,11 +442,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
442 for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
443 char *fname, *fname_old;
444
442 - if (!midx_cleared) {
443 - clear_midx_file(the_repository);
444 - midx_cleared = 1;
445 - }
446 -
445 fname = mkpathdup("%s/pack-%s%s", packdir,
446 item->string, exts[ext].name);
447 if (!file_exists(fname)) {
t/t5319-multi-pack-index.sh
+42 -2
@@ -348,12 +348,52 @@ test_expect_success 'repack with the --no-progress option' '
348 test_line_count = 0 err
349 '
350
351 -test_expect_success 'repack removes multi-pack-index' '
351 +test_expect_success 'repack removes multi-pack-index when deleting packs' '
352 test_path_is_file $objdir/pack/multi-pack-index &&
353 - GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf &&
353 + # Set GIT_TEST_MULTI_PACK_INDEX to 0 to avoid writing a new
354 + # multi-pack-index after repacking, but set "core.multiPackIndex" to
355 + # true so that "git repack" can read the existing MIDX.
356 + GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -adf &&
357 test_path_is_missing $objdir/pack/multi-pack-index
358 '
359
360 +test_expect_success 'repack preserves multi-pack-index when creating packs' '
361 + git init preserve &&
362 + test_when_finished "rm -fr preserve" &&
363 + (
364 + cd preserve &&
365 + packdir=.git/objects/pack &&
366 + midx=$packdir/multi-pack-index &&
367 +
368 + test_commit 1 &&
369 + pack1=$(git pack-objects --all $packdir/pack) &&
370 + touch $packdir/pack-$pack1.keep &&
371 + test_commit 2 &&
372 + pack2=$(git pack-objects --revs $packdir/pack) &&
373 + touch $packdir/pack-$pack2.keep &&
374 +
375 + git multi-pack-index write &&
376 + cp $midx $midx.bak &&
377 +
378 + cat >pack-input <<-EOF &&
379 + HEAD
380 + ^HEAD~1
381 + EOF
382 + test_commit 3 &&
383 + pack3=$(git pack-objects --revs $packdir/pack <pack-input) &&
384 + test_commit 4 &&
385 + pack4=$(git pack-objects --revs $packdir/pack <pack-input) &&
386 +
387 + GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -ad &&
388 + ls -la $packdir &&
389 + test_path_is_file $packdir/pack-$pack1.pack &&
390 + test_path_is_file $packdir/pack-$pack2.pack &&
391 + test_path_is_missing $packdir/pack-$pack3.pack &&
392 + test_path_is_missing $packdir/pack-$pack4.pack &&
393 + test_cmp_bin $midx.bak $midx
394 + )
395 +'
396 +
397 compare_results_with_midx "after repack"
398
399 test_expect_success 'multi-pack-index and pack-bitmap' '