Skip to content

Commit a9514e3

Browse files
committed
Merge branch 'tb/midx-repack-ignore-cruft-packs' into maint-2.38
"git multi-pack-index repack/expire" used to repack unreachable cruft into a new pack, which have been corrected. cf. <[email protected]> * tb/midx-repack-ignore-cruft-packs: midx.c: avoid cruft packs with non-zero `repack --batch-size` midx.c: remove unnecessary loop condition midx.c: replace `xcalloc()` with `CALLOC_ARRAY()` midx.c: avoid cruft packs with `repack --batch-size=0` midx.c: prevent `expire` from removing the cruft pack Documentation/git-multi-pack-index.txt: clarify expire behavior Documentation/git-multi-pack-index.txt: fix typo
2 parents 1b97c13 + b62ad56 commit a9514e3

File tree

3 files changed

+107
-6
lines changed

3 files changed

+107
-6
lines changed

Documentation/git-multi-pack-index.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ verify::
7070
Verify the contents of the MIDX file.
7171

7272
expire::
73-
Delete the pack-files that are tracked by the MIDX file, but
74-
have no objects referenced by the MIDX. Rewrite the MIDX file
75-
afterward to remove all references to these pack-files.
73+
Delete the pack-files that are tracked by the MIDX file, but
74+
have no objects referenced by the MIDX (with the exception of
75+
`.keep` packs and cruft packs). Rewrite the MIDX file afterward
76+
to remove all references to these pack-files.
7677

7778
repack::
7879
Create a new pack-file containing objects in small pack-files

midx.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
18391839
if (prepare_midx_pack(r, m, i))
18401840
continue;
18411841

1842-
if (m->packs[i]->pack_keep)
1842+
if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
18431843
continue;
18441844

18451845
pack_name = xstrdup(m->packs[i]->pack_name);
@@ -1895,6 +1895,8 @@ static int fill_included_packs_all(struct repository *r,
18951895
continue;
18961896
if (!pack_kept_objects && m->packs[i]->pack_keep)
18971897
continue;
1898+
if (m->packs[i]->is_cruft)
1899+
continue;
18981900

18991901
include_pack[i] = 1;
19001902
count++;
@@ -1910,9 +1912,11 @@ static int fill_included_packs_batch(struct repository *r,
19101912
{
19111913
uint32_t i, packs_to_repack;
19121914
size_t total_size;
1913-
struct repack_info *pack_info = xcalloc(m->num_packs, sizeof(struct repack_info));
1915+
struct repack_info *pack_info;
19141916
int pack_kept_objects = 0;
19151917

1918+
CALLOC_ARRAY(pack_info, m->num_packs);
1919+
19161920
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
19171921

19181922
for (i = 0; i < m->num_packs; i++) {
@@ -1924,7 +1928,7 @@ static int fill_included_packs_batch(struct repository *r,
19241928
pack_info[i].mtime = m->packs[i]->mtime;
19251929
}
19261930

1927-
for (i = 0; batch_size && i < m->num_objects; i++) {
1931+
for (i = 0; i < m->num_objects; i++) {
19281932
uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
19291933
pack_info[pack_int_id].referenced_objects++;
19301934
}
@@ -1942,6 +1946,8 @@ static int fill_included_packs_batch(struct repository *r,
19421946
continue;
19431947
if (!pack_kept_objects && p->pack_keep)
19441948
continue;
1949+
if (p->is_cruft)
1950+
continue;
19451951
if (open_pack_index(p) || !p->num_objects)
19461952
continue;
19471953

t/t5319-multi-pack-index.sh

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,70 @@ test_expect_success 'repack creates a new pack' '
784784
)
785785
'
786786

787+
test_expect_success 'repack (all) ignores cruft pack' '
788+
git init repo &&
789+
test_when_finished "rm -fr repo" &&
790+
(
791+
cd repo &&
792+
793+
test_commit base &&
794+
test_commit --no-tag unreachable &&
795+
796+
git reset --hard base &&
797+
git reflog expire --all --expire=all &&
798+
git repack --cruft -d &&
799+
800+
git multi-pack-index write &&
801+
802+
find $objdir/pack | sort >before &&
803+
git multi-pack-index repack --batch-size=0 &&
804+
find $objdir/pack | sort >after &&
805+
806+
test_cmp before after
807+
)
808+
'
809+
810+
test_expect_success 'repack (--batch-size) ignores cruft pack' '
811+
git init repo &&
812+
test_when_finished "rm -fr repo" &&
813+
(
814+
cd repo &&
815+
816+
test_commit_bulk 5 &&
817+
test_commit --no-tag unreachable &&
818+
819+
git reset --hard HEAD^ &&
820+
git reflog expire --all --expire=all &&
821+
git repack --cruft -d &&
822+
823+
test_commit four &&
824+
825+
find $objdir/pack -type f -name "*.pack" | sort >before &&
826+
git repack -d &&
827+
find $objdir/pack -type f -name "*.pack" | sort >after &&
828+
829+
pack="$(comm -13 before after)" &&
830+
test_file_size "$pack" >sz &&
831+
# Set --batch-size to twice the size of the pack created
832+
# in the previous step, since this is enough to
833+
# accommodate it and the cruft pack.
834+
#
835+
# This means that the MIDX machinery *could* combine the
836+
# new and cruft packs together.
837+
#
838+
# We ensure that it does not below.
839+
batch="$((($(cat sz) * 2)))" &&
840+
841+
git multi-pack-index write &&
842+
843+
find $objdir/pack | sort >before &&
844+
git multi-pack-index repack --batch-size=$batch &&
845+
find $objdir/pack | sort >after &&
846+
847+
test_cmp before after
848+
)
849+
'
850+
787851
test_expect_success 'expire removes repacked packs' '
788852
(
789853
cd dup &&
@@ -847,6 +911,36 @@ test_expect_success 'expire respects .keep files' '
847911
)
848912
'
849913

914+
test_expect_success 'expiring unreferenced cruft pack retains pack' '
915+
git init repo &&
916+
test_when_finished "rm -fr repo" &&
917+
(
918+
cd repo &&
919+
920+
test_commit base &&
921+
test_commit --no-tag unreachable &&
922+
unreachable=$(git rev-parse HEAD) &&
923+
924+
git reset --hard base &&
925+
git reflog expire --all --expire=all &&
926+
git repack --cruft -d &&
927+
mtimes="$(ls $objdir/pack/pack-*.mtimes)" &&
928+
929+
echo "base..$unreachable" >in &&
930+
pack="$(git pack-objects --revs --delta-base-offset \
931+
$objdir/pack/pack <in)" &&
932+
933+
# Preferring the contents of "$pack" will leave the
934+
# cruft pack unreferenced (ie., none of the objects
935+
# contained in the cruft pack will have their MIDX copy
936+
# selected from the cruft pack).
937+
git multi-pack-index write --preferred-pack="pack-$pack.pack" &&
938+
git multi-pack-index expire &&
939+
940+
test_path_is_file "$mtimes"
941+
)
942+
'
943+
850944
test_expect_success 'repack --batch-size=0 repacks everything' '
851945
cp -r dup dup2 &&
852946
(

0 commit comments

Comments
 (0)