diff options
-rw-r--r-- | builtin/repack.c | 38 | ||||
-rwxr-xr-x | t/t7700-repack.sh | 36 |
2 files changed, 50 insertions, 24 deletions
diff --git a/builtin/repack.c b/builtin/repack.c index f913e9a8a2..aea5ca9d44 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -105,46 +105,38 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list, struct string_list *fname_kept_list, const struct string_list *extra_keep) { - DIR *dir; - struct dirent *e; - char *fname; + struct packed_git *p; struct strbuf buf = STRBUF_INIT; - if (!(dir = opendir(packdir))) - return; - - while ((e = readdir(dir)) != NULL) { - size_t len; + for (p = get_all_packs(the_repository); p; p = p->next) { int i; + const char *base; - if (!strip_suffix(e->d_name, ".idx", &len)) + if (!p->pack_local) continue; - strbuf_reset(&buf); - strbuf_add(&buf, e->d_name, len); - strbuf_addstr(&buf, ".pack"); + base = pack_basename(p); for (i = 0; i < extra_keep->nr; i++) - if (!fspathcmp(buf.buf, extra_keep->items[i].string)) + if (!fspathcmp(base, extra_keep->items[i].string)) break; - fname = xmemdupz(e->d_name, len); + strbuf_reset(&buf); + strbuf_addstr(&buf, base); + strbuf_strip_suffix(&buf, ".pack"); - if ((extra_keep->nr > 0 && i < extra_keep->nr) || - (file_exists(mkpath("%s/%s.keep", packdir, fname)))) { - string_list_append_nodup(fname_kept_list, fname); - } else { + if ((extra_keep->nr > 0 && i < extra_keep->nr) || p->pack_keep) + string_list_append(fname_kept_list, buf.buf); + else { struct string_list_item *item; - item = string_list_append_nodup(fname_nonkept_list, - fname); - if (file_exists(mkpath("%s/%s.mtimes", packdir, fname))) + item = string_list_append(fname_nonkept_list, buf.buf); + if (p->is_cruft) item->util = (void*)(uintptr_t)CRUFT_PACK; } } - closedir(dir); - strbuf_release(&buf); string_list_sort(fname_kept_list); + strbuf_release(&buf); } static void remove_redundant_pack(const char *dir_name, const char *base_name) diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index af79266c58..27b66807cd 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -213,7 +213,7 @@ test_expect_success 'repack --keep-pack' ' test_create_repo keep-pack && ( cd keep-pack && - # avoid producing difference packs to delta/base choices + # avoid producing different packs due to delta/base choices git config pack.window 0 && P1=$(commit_and_pack 1) && P2=$(commit_and_pack 2) && @@ -239,6 +239,10 @@ test_expect_success 'repack --keep-pack' ' mv "$from" "$to" || return 1 done && + # A .idx file without a .pack should not stop us from + # repacking what we can. + touch .git/objects/pack/pack-does-not-exist.idx && + git repack --cruft -d --keep-pack $P1 --keep-pack $P4 && ls .git/objects/pack/*.pack >newer-counts && @@ -247,6 +251,36 @@ test_expect_success 'repack --keep-pack' ' ) ' +test_expect_success 'repacking fails when missing .pack actually means missing objects' ' + test_create_repo idx-without-pack && + ( + cd idx-without-pack && + + # Avoid producing different packs due to delta/base choices + git config pack.window 0 && + P1=$(commit_and_pack 1) && + P2=$(commit_and_pack 2) && + P3=$(commit_and_pack 3) && + P4=$(commit_and_pack 4) && + ls .git/objects/pack/*.pack >old-counts && + test_line_count = 4 old-counts && + + # Remove one .pack file + rm .git/objects/pack/$P2 && + + ls .git/objects/pack/*.pack >before-pack-dir && + + test_must_fail git fsck && + test_must_fail git repack --cruft -d 2>err && + grep "bad object" err && + + # Before failing, the repack did not modify the + # pack directory. + ls .git/objects/pack/*.pack >after-pack-dir && + test_cmp before-pack-dir after-pack-dir + ) +' + test_expect_success 'bitmaps are created by default in bare repos' ' git clone --bare .git bare.git && rm -f bare.git/objects/pack/*.bitmap && |