Merge branch 'tb/repack-clearing-midx'

When a packfile is removed by "git repack", multi-pack-index gets
cleared; the code was taught to do so less aggressively by first
checking if the midx actually refers to a pack that no longer
exists.

* tb/repack-clearing-midx:
  midx: traverse the local MIDX first
  builtin/repack.c: invalidate MIDX only when necessary
This commit is contained in:
Junio C Hamano 2020-09-09 13:53:06 -07:00
commit a31677dde3
5 changed files with 65 additions and 11 deletions

View File

@ -133,7 +133,11 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
static void remove_redundant_pack(const char *dir_name, const char *base_name)
{
struct strbuf buf = STRBUF_INIT;
strbuf_addf(&buf, "%s/%s.pack", dir_name, base_name);
struct multi_pack_index *m = get_local_multi_pack_index(the_repository);
strbuf_addf(&buf, "%s.pack", base_name);
if (m && midx_contains_pack(m, buf.buf))
clear_midx_file(the_repository);
strbuf_insertf(&buf, 0, "%s/", dir_name);
unlink_pack_path(buf.buf, 1);
strbuf_release(&buf);
}
@ -286,7 +290,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
int keep_unreachable = 0;
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
int no_update_server_info = 0;
int midx_cleared = 0;
struct pack_objects_args po_args = {NULL};
struct option builtin_repack_options[] = {
@ -439,11 +442,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
char *fname, *fname_old;
if (!midx_cleared) {
clear_midx_file(the_repository);
midx_cleared = 1;
}
fname = mkpathdup("%s/pack-%s%s", packdir,
item->string, exts[ext].name);
if (!file_exists(fname)) {

8
midx.c
View File

@ -416,8 +416,12 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i
m = load_multi_pack_index(object_dir, local);
if (m) {
m->next = r->objects->multi_pack_index;
r->objects->multi_pack_index = m;
struct multi_pack_index *mp = r->objects->multi_pack_index;
if (mp) {
m->next = mp->next;
mp->next = m;
} else
r->objects->multi_pack_index = m;
return 1;
}

View File

@ -1027,6 +1027,17 @@ struct multi_pack_index *get_multi_pack_index(struct repository *r)
return r->objects->multi_pack_index;
}
struct multi_pack_index *get_local_multi_pack_index(struct repository *r)
{
struct multi_pack_index *m = get_multi_pack_index(r);
/* no need to iterate; we always put the local one first (if any) */
if (m && m->local)
return m;
return NULL;
}
struct packed_git *get_all_packs(struct repository *r)
{
struct multi_pack_index *m;

View File

@ -57,6 +57,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack);
struct packed_git *get_packed_git(struct repository *r);
struct list_head *get_packed_git_mru(struct repository *r);
struct multi_pack_index *get_multi_pack_index(struct repository *r);
struct multi_pack_index *get_local_multi_pack_index(struct repository *r);
struct packed_git *get_all_packs(struct repository *r);
/*

View File

@ -382,12 +382,52 @@ test_expect_success 'repack with the --no-progress option' '
test_line_count = 0 err
'
test_expect_success 'repack removes multi-pack-index' '
test_expect_success 'repack removes multi-pack-index when deleting packs' '
test_path_is_file $objdir/pack/multi-pack-index &&
GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf &&
# Set GIT_TEST_MULTI_PACK_INDEX to 0 to avoid writing a new
# multi-pack-index after repacking, but set "core.multiPackIndex" to
# true so that "git repack" can read the existing MIDX.
GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -adf &&
test_path_is_missing $objdir/pack/multi-pack-index
'
test_expect_success 'repack preserves multi-pack-index when creating packs' '
git init preserve &&
test_when_finished "rm -fr preserve" &&
(
cd preserve &&
packdir=.git/objects/pack &&
midx=$packdir/multi-pack-index &&
test_commit 1 &&
pack1=$(git pack-objects --all $packdir/pack) &&
touch $packdir/pack-$pack1.keep &&
test_commit 2 &&
pack2=$(git pack-objects --revs $packdir/pack) &&
touch $packdir/pack-$pack2.keep &&
git multi-pack-index write &&
cp $midx $midx.bak &&
cat >pack-input <<-EOF &&
HEAD
^HEAD~1
EOF
test_commit 3 &&
pack3=$(git pack-objects --revs $packdir/pack <pack-input) &&
test_commit 4 &&
pack4=$(git pack-objects --revs $packdir/pack <pack-input) &&
GIT_TEST_MULTI_PACK_INDEX=0 git -c core.multiPackIndex repack -ad &&
ls -la $packdir &&
test_path_is_file $packdir/pack-$pack1.pack &&
test_path_is_file $packdir/pack-$pack2.pack &&
test_path_is_missing $packdir/pack-$pack3.pack &&
test_path_is_missing $packdir/pack-$pack4.pack &&
test_cmp_bin $midx.bak $midx
)
'
compare_results_with_midx "after repack"
test_expect_success 'multi-pack-index and pack-bitmap' '