f25e33c156
In 0fabafd0b9
(builtin/repack.c: add '--geometric' option, 2021-02-22),
the 'git repack --geometric' code aborts early when there is zero or one
pack.
When there are no packs, this code does the right thing by placing the
split at "0". But when there is exactly one pack, the split is placed at
"1", which means that "git repack --geometric" (with any factor)
repacks all of the objects in a single pack.
This is wasteful, and the remaining code in split_pack_geometry() does
the right thing (not repacking the objects in a single pack) even when
only one pack is present.
Loosen the guard to only stop when there aren't any packs, and let the
rest of the code do the right thing. Add a test to ensure that this is
the case.
Noticed-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
153 lines
3.8 KiB
Bash
Executable File
153 lines
3.8 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='git repack --geometric works correctly'
|
|
|
|
. ./test-lib.sh
|
|
|
|
GIT_TEST_MULTI_PACK_INDEX=0
|
|
|
|
objdir=.git/objects
|
|
midx=$objdir/pack/multi-pack-index
|
|
|
|
test_expect_success '--geometric with no packs' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
git repack --geometric 2 >out &&
|
|
test_i18ngrep "Nothing new to pack" out
|
|
)
|
|
'
|
|
|
|
test_expect_success '--geometric with one pack' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
test_commit "base" &&
|
|
git repack -d &&
|
|
|
|
git repack --geometric 2 >out &&
|
|
|
|
test_i18ngrep "Nothing new to pack" out
|
|
)
|
|
'
|
|
|
|
test_expect_success '--geometric with an intact progression' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
# These packs already form a geometric progression.
|
|
test_commit_bulk --start=1 1 && # 3 objects
|
|
test_commit_bulk --start=2 2 && # 6 objects
|
|
test_commit_bulk --start=4 4 && # 12 objects
|
|
|
|
find $objdir/pack -name "*.pack" | sort >expect &&
|
|
git repack --geometric 2 -d &&
|
|
find $objdir/pack -name "*.pack" | sort >actual &&
|
|
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_expect_success '--geometric with small-pack rollup' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
test_commit_bulk --start=1 1 && # 3 objects
|
|
test_commit_bulk --start=2 1 && # 3 objects
|
|
find $objdir/pack -name "*.pack" | sort >small &&
|
|
test_commit_bulk --start=3 4 && # 12 objects
|
|
test_commit_bulk --start=7 8 && # 24 objects
|
|
find $objdir/pack -name "*.pack" | sort >before &&
|
|
|
|
git repack --geometric 2 -d &&
|
|
|
|
# Three packs in total; two of the existing large ones, and one
|
|
# new one.
|
|
find $objdir/pack -name "*.pack" | sort >after &&
|
|
test_line_count = 3 after &&
|
|
comm -3 small before | tr -d "\t" >large &&
|
|
grep -qFf large after
|
|
)
|
|
'
|
|
|
|
test_expect_success '--geometric with small- and large-pack rollup' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
# size(small1) + size(small2) > size(medium) / 2
|
|
test_commit_bulk --start=1 1 && # 3 objects
|
|
test_commit_bulk --start=2 1 && # 3 objects
|
|
test_commit_bulk --start=2 3 && # 7 objects
|
|
test_commit_bulk --start=6 9 && # 27 objects &&
|
|
|
|
find $objdir/pack -name "*.pack" | sort >before &&
|
|
|
|
git repack --geometric 2 -d &&
|
|
|
|
find $objdir/pack -name "*.pack" | sort >after &&
|
|
comm -12 before after >untouched &&
|
|
|
|
# Two packs in total; the largest pack from before running "git
|
|
# repack", and one new one.
|
|
test_line_count = 1 untouched &&
|
|
test_line_count = 2 after
|
|
)
|
|
'
|
|
|
|
test_expect_success '--geometric ignores kept packs' '
|
|
git init geometric &&
|
|
test_when_finished "rm -fr geometric" &&
|
|
(
|
|
cd geometric &&
|
|
|
|
test_commit kept && # 3 objects
|
|
test_commit pack && # 3 objects
|
|
|
|
KEPT=$(git pack-objects --revs $objdir/pack/pack <<-EOF
|
|
refs/tags/kept
|
|
EOF
|
|
) &&
|
|
PACK=$(git pack-objects --revs $objdir/pack/pack <<-EOF
|
|
refs/tags/pack
|
|
^refs/tags/kept
|
|
EOF
|
|
) &&
|
|
|
|
# neither pack contains more than twice the number of objects in
|
|
# the other, so they should be combined. but, marking one as
|
|
# .kept on disk will "freeze" it, so the pack structure should
|
|
# remain unchanged.
|
|
touch $objdir/pack/pack-$KEPT.keep &&
|
|
|
|
find $objdir/pack -name "*.pack" | sort >before &&
|
|
git repack --geometric 2 -d &&
|
|
find $objdir/pack -name "*.pack" | sort >after &&
|
|
|
|
# both packs should still exist
|
|
test_path_is_file $objdir/pack/pack-$KEPT.pack &&
|
|
test_path_is_file $objdir/pack/pack-$PACK.pack &&
|
|
|
|
# and no new packs should be created
|
|
test_cmp before after &&
|
|
|
|
# Passing --pack-kept-objects causes packs with a .keep file to
|
|
# be repacked, too.
|
|
git repack --geometric 2 -d --pack-kept-objects &&
|
|
|
|
find $objdir/pack -name "*.pack" >after &&
|
|
test_line_count = 1 after
|
|
)
|
|
'
|
|
|
|
test_done
|