Browse Source

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
maint
Junio C Hamano 5 years ago
parent
commit
a31677dde3
  1. 12
      builtin/repack.c
  2. 8
      midx.c
  3. 11
      packfile.c
  4. 1
      packfile.h
  5. 44
      t/t5319-multi-pack-index.sh

12
builtin/repack.c

@ -133,7 +133,11 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list, @@ -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) @@ -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) @@ -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

@ -416,8 +416,12 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i @@ -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;
}


11
packfile.c

@ -1027,6 +1027,17 @@ struct multi_pack_index *get_multi_pack_index(struct repository *r) @@ -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;

1
packfile.h

@ -57,6 +57,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack); @@ -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);

/*

44
t/t5319-multi-pack-index.sh

@ -382,12 +382,52 @@ test_expect_success 'repack with the --no-progress option' ' @@ -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' '

Loading…
Cancel
Save