diff options
Diffstat (limited to 't/t6500-gc.sh')
-rwxr-xr-x | t/t6500-gc.sh | 236 |
1 files changed, 217 insertions, 19 deletions
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 0a69a67..43d4017 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -10,7 +10,8 @@ test_expect_success 'setup' ' # do not let the amount of physical memory affects gc # behavior, make sure we always pack everything to one pack by # default - git config gc.bigPackThreshold 2g + git config gc.bigPackThreshold 2g && + test_oid_init ' test_expect_success 'gc empty repository' ' @@ -24,7 +25,7 @@ test_expect_success 'gc does not leave behind pid file' ' test_expect_success 'gc --gobbledegook' ' test_expect_code 129 git gc --nonsense 2>err && - test_i18ngrep "[Uu]sage: git gc" err + test_grep "[Uu]sage: git gc" err ' test_expect_success 'gc -h with invalid configuration' ' @@ -35,7 +36,7 @@ test_expect_success 'gc -h with invalid configuration' ' echo "[gc] pruneexpire = CORRUPT" >>.git/config && test_expect_code 129 git gc -h >usage 2>&1 ) && - test_i18ngrep "[Uu]sage" broken/usage + test_grep "[Uu]sage" broken/usage ' test_expect_success 'gc is not aborted due to a stale symref' ' @@ -61,7 +62,7 @@ test_expect_success 'gc --keep-largest-pack' ' git gc && ( cd .git/objects/pack && ls *.pack ) >pack-list && test_line_count = 1 pack-list && - BASE_PACK=.git/objects/pack/pack-*.pack && + cp pack-list base-pack-list && test_commit four && git repack -d && test_commit five && @@ -73,11 +74,55 @@ test_expect_success 'gc --keep-largest-pack' ' test_line_count = 2 pack-list && awk "/^P /{print \$2}" <.git/objects/info/packs >pack-info && test_line_count = 2 pack-info && - test_path_is_file $BASE_PACK && + test_path_is_file .git/objects/pack/$(cat base-pack-list) && git fsck ) ' +test_expect_success 'pre-auto-gc hook can stop auto gc' ' + cat >err.expect <<-\EOF && + no gc for you + EOF + + git init pre-auto-gc-hook && + test_hook -C pre-auto-gc-hook pre-auto-gc <<-\EOF && + echo >&2 no gc for you && + exit 1 + EOF + ( + cd pre-auto-gc-hook && + + git config gc.auto 3 && + git config gc.autoDetach false && + + # We need to create two object whose sha1s start with 17 + # since this is what git gc counts. As it happens, these + # two blobs will do so. + test_commit "$(test_oid blob17_1)" && + test_commit "$(test_oid blob17_2)" && + + git gc --auto >../out.actual 2>../err.actual + ) && + test_must_be_empty out.actual && + test_cmp err.expect err.actual && + + cat >err.expect <<-\EOF && + will gc for you + Auto packing the repository for optimum performance. + See "git help gc" for manual housekeeping. + EOF + + test_hook -C pre-auto-gc-hook --clobber pre-auto-gc <<-\EOF && + echo >&2 will gc for you && + exit 0 + EOF + + git -C pre-auto-gc-hook gc --auto >out.actual 2>err.actual && + + test_must_be_empty out.actual && + test_cmp err.expect err.actual +' + test_expect_success 'auto gc with too many loose objects does not attempt to create bitmaps' ' test_config gc.auto 3 && test_config gc.autodetach false && @@ -85,35 +130,35 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre # We need to create two object whose sha1s start with 17 # since this is what git gc counts. As it happens, these # two blobs will do so. - test_commit 263 && - test_commit 410 && + test_commit "$(test_oid blob17_1)" && + test_commit "$(test_oid blob17_2)" && # Our first gc will create a pack; our second will create a second pack git gc --auto && - ls .git/objects/pack | sort >existing_packs && - test_commit 523 && - test_commit 790 && + ls .git/objects/pack/pack-*.pack | sort >existing_packs && + test_commit "$(test_oid blob17_3)" && + test_commit "$(test_oid blob17_4)" && git gc --auto 2>err && - test_i18ngrep ! "^warning:" err && - ls .git/objects/pack/ | sort >post_packs && + test_grep ! "^warning:" err && + ls .git/objects/pack/pack-*.pack | sort >post_packs && comm -1 -3 existing_packs post_packs >new && comm -2 -3 existing_packs post_packs >del && test_line_count = 0 del && # No packs are deleted - test_line_count = 2 new # There is one new pack and its .idx + test_line_count = 1 new # There is one new pack ' test_expect_success 'gc --no-quiet' ' GIT_PROGRESS_DELAY=0 git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && test_must_be_empty stdout && - test_i18ngrep "Computing commit graph generation numbers" stderr + test_grep "Computing commit graph generation numbers" stderr ' test_expect_success TTY 'with TTY: gc --no-quiet' ' test_terminal env GIT_PROGRESS_DELAY=0 \ git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && test_must_be_empty stdout && - test_i18ngrep "Enumerating objects" stderr && - test_i18ngrep "Computing commit graph generation numbers" stderr + test_grep "Enumerating objects" stderr && + test_grep "Computing commit graph generation numbers" stderr ' test_expect_success 'gc --quiet' ' @@ -141,6 +186,158 @@ test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "e grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out ' +test_expect_success 'gc.repackFilter launches repack with a filter' ' + git clone --no-local --bare . bare.git && + + git -C bare.git -c gc.cruftPacks=false gc && + test_stdout_line_count = 1 ls bare.git/objects/pack/*.pack && + + GIT_TRACE=$(pwd)/trace.out git -C bare.git -c gc.repackFilter=blob:none \ + -c repack.writeBitmaps=false -c gc.cruftPacks=false gc && + test_stdout_line_count = 2 ls bare.git/objects/pack/*.pack && + grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out +' + +test_expect_success 'gc.repackFilterTo store filtered out objects' ' + test_when_finished "rm -rf bare.git filtered.git" && + + git init --bare filtered.git && + git -C bare.git -c gc.repackFilter=blob:none \ + -c gc.repackFilterTo=../filtered.git/objects/pack/pack \ + -c repack.writeBitmaps=false -c gc.cruftPacks=false gc && + + test_stdout_line_count = 1 ls bare.git/objects/pack/*.pack && + test_stdout_line_count = 1 ls filtered.git/objects/pack/*.pack +' + +prepare_cruft_history () { + test_commit base && + + test_commit --no-tag foo && + test_commit --no-tag bar && + git reset HEAD^^ +} + +assert_no_cruft_packs () { + find .git/objects/pack -name "*.mtimes" >mtimes && + test_must_be_empty mtimes +} + +for argv in \ + "gc" \ + "-c gc.cruftPacks=true gc" \ + "-c gc.cruftPacks=false gc --cruft" +do + test_expect_success "git $argv generates a cruft pack" ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + prepare_cruft_history && + git $argv && + + find .git/objects/pack -name "*.mtimes" >mtimes && + sed -e 's/\.mtimes$/\.pack/g' mtimes >packs && + + test_file_not_empty packs && + while read pack + do + test_path_is_file "$pack" || return 1 + done <packs + ) + ' +done + +for argv in \ + "gc --no-cruft" \ + "-c gc.cruftPacks=false gc" \ + "-c gc.cruftPacks=true gc --no-cruft" +do + test_expect_success "git $argv does not generate a cruft pack" ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + prepare_cruft_history && + git $argv && + + assert_no_cruft_packs + ) + ' +done + +test_expect_success '--keep-largest-pack ignores cruft packs' ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + # Generate a pack for reachable objects (of which there + # are 3), and one for unreachable objects (of which + # there are 6). + prepare_cruft_history && + git gc --cruft && + + mtimes="$(find .git/objects/pack -type f -name "pack-*.mtimes")" && + sz="$(test_file_size "${mtimes%.mtimes}.pack")" && + + # Ensure that the cruft pack gets removed (due to + # `--prune=now`) despite it being the largest pack. + git -c gc.bigPackThreshold=$sz gc --cruft --prune=now && + + assert_no_cruft_packs + ) +' + +test_expect_success 'gc.bigPackThreshold ignores cruft packs' ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + # Generate a pack for reachable objects (of which there + # are 3), and one for unreachable objects (of which + # there are 6). + prepare_cruft_history && + git gc --cruft && + + # Ensure that the cruft pack gets removed (due to + # `--prune=now`) despite it being the largest pack. + git gc --cruft --prune=now --keep-largest-pack && + + assert_no_cruft_packs + ) +' + +cruft_max_size_opts="git repack -d -l --cruft --cruft-expiration=2.weeks.ago" + +test_expect_success 'setup for --max-cruft-size tests' ' + git init cruft--max-size && + ( + cd cruft--max-size && + prepare_cruft_history + ) +' + +test_expect_success '--max-cruft-size sets appropriate repack options' ' + GIT_TRACE2_EVENT=$(pwd)/trace2.txt git -C cruft--max-size \ + gc --cruft --max-cruft-size=1M && + test_subcommand $cruft_max_size_opts --max-cruft-size=1048576 <trace2.txt +' + +test_expect_success 'gc.maxCruftSize sets appropriate repack options' ' + GIT_TRACE2_EVENT=$(pwd)/trace2.txt \ + git -C cruft--max-size -c gc.maxCruftSize=2M gc --cruft && + test_subcommand $cruft_max_size_opts --max-cruft-size=2097152 <trace2.txt && + + GIT_TRACE2_EVENT=$(pwd)/trace2.txt \ + git -C cruft--max-size -c gc.maxCruftSize=2M gc --cruft \ + --max-cruft-size=3M && + test_subcommand $cruft_max_size_opts --max-cruft-size=3145728 <trace2.txt +' + run_and_wait_for_auto_gc () { # We read stdout from gc for the side effect of waiting until the # background gc process exits, closing its fd 9. Furthermore, the @@ -159,7 +356,7 @@ test_expect_success 'background auto gc does not run if gc.log is present and re test_config gc.autodetach true && echo fleem >.git/gc.log && git gc --auto 2>err && - test_i18ngrep "^warning:" err && + test_grep "^warning:" err && test_config gc.logexpiry 5.days && test-tool chmtime =-345600 .git/gc.log && git gc --auto && @@ -178,7 +375,7 @@ test_expect_success 'background auto gc respects lock for all operations' ' # create a ref whose loose presence we can use to detect a pack-refs run git update-ref refs/heads/should-be-loose HEAD && - test_path_is_file .git/refs/heads/should-be-loose && + (ls -1 .git/refs/heads .git/reftable >expect || true) && # now fake a concurrent gc that holds the lock; we can use our # shell pid so that it looks valid. @@ -195,7 +392,8 @@ test_expect_success 'background auto gc respects lock for all operations' ' # our gc should exit zero without doing anything run_and_wait_for_auto_gc && - test_path_is_file .git/refs/heads/should-be-loose + (ls -1 .git/refs/heads .git/reftable >actual || true) && + test_cmp expect actual ' # DO NOT leave a detached auto gc process running near the end of the |