#!/bin/sh global test_description := ''git repack works correctly'' source ./test-lib.sh test_expect_success 'objects in packs marked .keep are not repacked' ' echo content1 > file1 && echo content2 > file2 && git add . && test_tick && git commit -m initial_commit && # Create two packs # The first pack will contain all of the objects except one git rev-list --objects --all | grep -v file2 | git pack-objects pack > /dev/null && # The second pack will contain the excluded object packsha1=$(git rev-list --objects --all | grep file2 | git pack-objects pack) && >pack-$packsha1.keep && objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 | sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") && mv pack-* .git/objects/pack/ && git repack -A -d -l && git prune-packed && for p in .git/objects/pack/*.idx; do idx=$(basename $p) test "pack-$packsha1.idx" = "$idx" && continue if git verify-pack -v $p | egrep "^$objsha1"; then found_duplicate_object=1 echo "DUPLICATE OBJECT FOUND" break fi done && test -z "$found_duplicate_object" ' test_expect_success 'writing bitmaps via command-line can duplicate .keep objects' ' # build on $objsha1, $packsha1, and .keep state from previous git repack -Adbl && test_when_finished "found_duplicate_object=" && for p in .git/objects/pack/*.idx; do idx=$(basename $p) test "pack-$packsha1.idx" = "$idx" && continue if git verify-pack -v $p | egrep "^$objsha1"; then found_duplicate_object=1 echo "DUPLICATE OBJECT FOUND" break fi done && test "$found_duplicate_object" = 1 ' test_expect_success 'writing bitmaps via config can duplicate .keep objects' ' # build on $objsha1, $packsha1, and .keep state from previous git -c repack.writebitmaps=true repack -Adl && test_when_finished "found_duplicate_object=" && for p in .git/objects/pack/*.idx; do idx=$(basename $p) test "pack-$packsha1.idx" = "$idx" && continue if git verify-pack -v $p | egrep "^$objsha1"; then found_duplicate_object=1 echo "DUPLICATE OBJECT FOUND" break fi done && test "$found_duplicate_object" = 1 ' test_expect_success 'loose objects in alternate ODB are not repacked' ' mkdir alt_objects && echo $(pwd)/alt_objects > .git/objects/info/alternates && echo content3 > file3 && objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) && git add file3 && test_tick && git commit -m commit_file3 && git repack -a -d -l && git prune-packed && for p in .git/objects/pack/*.idx; do if git verify-pack -v $p | egrep "^$objsha1"; then found_duplicate_object=1 echo "DUPLICATE OBJECT FOUND" break fi done && test -z "$found_duplicate_object" ' test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' ' mkdir alt_objects/pack && mv .git/objects/pack/* alt_objects/pack && git repack -a && myidx=$(ls -1 .git/objects/pack/*.idx) && test -f "$myidx" && for p in alt_objects/pack/*.idx; do git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" done | while read sha1 rest; do if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then echo "Missing object in local pack: $sha1" return 1 fi done ' test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' ' rm -f .git/objects/pack/* && echo new_content >> file1 && git add file1 && test_tick && git commit -m more_content && git repack && git repack -a -d && myidx=$(ls -1 .git/objects/pack/*.idx) && test -f "$myidx" && for p in alt_objects/pack/*.idx; do git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" done | while read sha1 rest; do if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then echo "Missing object in local pack: $sha1" return 1 fi done ' test_expect_success 'packed obs in alternate ODB kept pack are repacked' ' # swap the .keep so the commit object is in the pack with .keep for p in alt_objects/pack/*.pack do base_name=$(basename $p .pack) && if test -f alt_objects/pack/$base_name.keep then rm alt_objects/pack/$base_name.keep else touch alt_objects/pack/$base_name.keep fi done && git repack -a -d && myidx=$(ls -1 .git/objects/pack/*.idx) && test -f "$myidx" && for p in alt_objects/pack/*.idx; do git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" done | while read sha1 rest; do if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then echo "Missing object in local pack: $sha1" return 1 fi done ' test_expect_success 'packed unreachable obs in alternate ODB are not loosened' ' rm -f alt_objects/pack/*.keep && mv .git/objects/pack/* alt_objects/pack/ && csha1=$(git rev-parse HEAD^{commit}) && git reset --hard HEAD^ && test_tick && git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && # The pack-objects call on the next line is equivalent to # git repack -A -d without the call to prune-packed git pack-objects --honor-pack-keep --non-empty --all --reflog \ --unpack-unreachable .git/objects/info/alternates && test_must_fail git show $csha1 ' test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' ' echo $(pwd)/alt_objects > .git/objects/info/alternates && echo "$csha1" | git pack-objects --non-empty --all --reflog pack && rm -f .git/objects/pack/* && mv pack-* .git/objects/pack/ && # The pack-objects call on the next line is equivalent to # git repack -A -d without the call to prune-packed git pack-objects --honor-pack-keep --non-empty --all --reflog \ --unpack-unreachable .git/objects/info/alternates && test_must_fail git show $csha1 ' test_expect_success 'objects made unreachable by grafts only are kept' ' test_tick && git commit --allow-empty -m "commit 4" && H0=$(git rev-parse HEAD) && H1=$(git rev-parse HEAD^) && H2=$(git rev-parse HEAD^^) && echo "$H0 $H2" > .git/info/grafts && git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && git repack -a -d && git cat-file -t $H1 ' test_done (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"git repack works correctly">)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(SQ <"objects in packs marked .keep are not repacked">)} { (SQ <"\n"> <"\techo content1 > file1 &&\n"> <"\techo content2 > file2 &&\n"> <"\tgit add . &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m initial_commit &&\n"> <"\t# Create two packs\n"> <"\t# The first pack will contain all of the objects except one\n"> <"\tgit rev-list --objects --all | grep -v file2 |\n"> <"\t\tgit pack-objects pack > /dev/null &&\n"> <"\t# The second pack will contain the excluded object\n"> <"\tpacksha1=$(git rev-list --objects --all | grep file2 |\n"> <"\t\tgit pack-objects pack) &&\n"> <"\t>pack-$packsha1.keep &&\n"> <"\tobjsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |\n"> <"\t\tsed -e \"s/^\\([0-9a-f]\\{40\\}\\).*/\\1/\") &&\n"> <"\tmv pack-* .git/objects/pack/ &&\n"> <"\tgit repack -A -d -l &&\n"> <"\tgit prune-packed &&\n"> <"\tfor p in .git/objects/pack/*.idx; do\n"> <"\t\tidx=$(basename $p)\n"> <"\t\ttest \"pack-$packsha1.idx\" = \"$idx\" && continue\n"> <"\t\tif git verify-pack -v $p | egrep \"^$objsha1\"; then\n"> <"\t\t\tfound_duplicate_object=1\n"> <"\t\t\techo \"DUPLICATE OBJECT FOUND\"\n"> <"\t\t\tbreak\n"> <"\t\tfi\n"> <"\tdone &&\n"> <"\ttest -z \"$found_duplicate_object\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"writing bitmaps via command-line can duplicate .keep objects">)} { (SQ <"\n"> <"\t# build on $objsha1, $packsha1, and .keep state from previous\n"> <"\tgit repack -Adbl &&\n"> <"\ttest_when_finished \"found_duplicate_object=\" &&\n"> <"\tfor p in .git/objects/pack/*.idx; do\n"> <"\t\tidx=$(basename $p)\n"> <"\t\ttest \"pack-$packsha1.idx\" = \"$idx\" && continue\n"> <"\t\tif git verify-pack -v $p | egrep \"^$objsha1\"; then\n"> <"\t\t\tfound_duplicate_object=1\n"> <"\t\t\techo \"DUPLICATE OBJECT FOUND\"\n"> <"\t\t\tbreak\n"> <"\t\tfi\n"> <"\tdone &&\n"> <"\ttest \"$found_duplicate_object\" = 1\n"> ) } ) (C {(test_expect_success)} {(SQ <"writing bitmaps via config can duplicate .keep objects">)} { (SQ <"\n"> <"\t# build on $objsha1, $packsha1, and .keep state from previous\n"> <"\tgit -c repack.writebitmaps=true repack -Adl &&\n"> <"\ttest_when_finished \"found_duplicate_object=\" &&\n"> <"\tfor p in .git/objects/pack/*.idx; do\n"> <"\t\tidx=$(basename $p)\n"> <"\t\ttest \"pack-$packsha1.idx\" = \"$idx\" && continue\n"> <"\t\tif git verify-pack -v $p | egrep \"^$objsha1\"; then\n"> <"\t\t\tfound_duplicate_object=1\n"> <"\t\t\techo \"DUPLICATE OBJECT FOUND\"\n"> <"\t\t\tbreak\n"> <"\t\tfi\n"> <"\tdone &&\n"> <"\ttest \"$found_duplicate_object\" = 1\n"> ) } ) (C {(test_expect_success)} {(SQ <"loose objects in alternate ODB are not repacked">)} { (SQ <"\n"> <"\tmkdir alt_objects &&\n"> <"\techo $(pwd)/alt_objects > .git/objects/info/alternates &&\n"> <"\techo content3 > file3 &&\n"> <"\tobjsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&\n"> <"\tgit add file3 &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m commit_file3 &&\n"> <"\tgit repack -a -d -l &&\n"> <"\tgit prune-packed &&\n"> <"\tfor p in .git/objects/pack/*.idx; do\n"> <"\t\tif git verify-pack -v $p | egrep \"^$objsha1\"; then\n"> <"\t\t\tfound_duplicate_object=1\n"> <"\t\t\techo \"DUPLICATE OBJECT FOUND\"\n"> <"\t\t\tbreak\n"> <"\t\tfi\n"> <"\tdone &&\n"> <"\ttest -z \"$found_duplicate_object\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"packed obs in alt ODB are repacked even when local repo is packless">)} { (SQ <"\n"> <"\tmkdir alt_objects/pack &&\n"> <"\tmv .git/objects/pack/* alt_objects/pack &&\n"> <"\tgit repack -a &&\n"> <"\tmyidx=$(ls -1 .git/objects/pack/*.idx) &&\n"> <"\ttest -f \"$myidx\" &&\n"> <"\tfor p in alt_objects/pack/*.idx; do\n"> <"\t\tgit verify-pack -v $p | sed -n -e \"/^[0-9a-f]\\{40\\}/p\"\n"> <"\tdone | while read sha1 rest; do\n"> <"\t\tif ! ( git verify-pack -v $myidx | grep \"^$sha1\" ); then\n"> <"\t\t\techo \"Missing object in local pack: $sha1\"\n"> <"\t\t\treturn 1\n"> <"\t\tfi\n"> <"\tdone\n"> ) } ) (C {(test_expect_success)} {(SQ <"packed obs in alt ODB are repacked when local repo has packs">)} { (SQ <"\n"> <"\trm -f .git/objects/pack/* &&\n"> <"\techo new_content >> file1 &&\n"> <"\tgit add file1 &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m more_content &&\n"> <"\tgit repack &&\n"> <"\tgit repack -a -d &&\n"> <"\tmyidx=$(ls -1 .git/objects/pack/*.idx) &&\n"> <"\ttest -f \"$myidx\" &&\n"> <"\tfor p in alt_objects/pack/*.idx; do\n"> <"\t\tgit verify-pack -v $p | sed -n -e \"/^[0-9a-f]\\{40\\}/p\"\n"> <"\tdone | while read sha1 rest; do\n"> <"\t\tif ! ( git verify-pack -v $myidx | grep \"^$sha1\" ); then\n"> <"\t\t\techo \"Missing object in local pack: $sha1\"\n"> <"\t\t\treturn 1\n"> <"\t\tfi\n"> <"\tdone\n"> ) } ) (C {(test_expect_success)} {(SQ <"packed obs in alternate ODB kept pack are repacked">)} { (SQ <"\n"> <"\t# swap the .keep so the commit object is in the pack with .keep\n"> <"\tfor p in alt_objects/pack/*.pack\n"> <"\tdo\n"> <"\t\tbase_name=$(basename $p .pack) &&\n"> <"\t\tif test -f alt_objects/pack/$base_name.keep\n"> <"\t\tthen\n"> <"\t\t\trm alt_objects/pack/$base_name.keep\n"> <"\t\telse\n"> <"\t\t\ttouch alt_objects/pack/$base_name.keep\n"> <"\t\tfi\n"> <"\tdone &&\n"> <"\tgit repack -a -d &&\n"> <"\tmyidx=$(ls -1 .git/objects/pack/*.idx) &&\n"> <"\ttest -f \"$myidx\" &&\n"> <"\tfor p in alt_objects/pack/*.idx; do\n"> <"\t\tgit verify-pack -v $p | sed -n -e \"/^[0-9a-f]\\{40\\}/p\"\n"> <"\tdone | while read sha1 rest; do\n"> <"\t\tif ! ( git verify-pack -v $myidx | grep \"^$sha1\" ); then\n"> <"\t\t\techo \"Missing object in local pack: $sha1\"\n"> <"\t\t\treturn 1\n"> <"\t\tfi\n"> <"\tdone\n"> ) } ) (C {(test_expect_success)} {(SQ <"packed unreachable obs in alternate ODB are not loosened">)} { (SQ <"\n"> <"\trm -f alt_objects/pack/*.keep &&\n"> <"\tmv .git/objects/pack/* alt_objects/pack/ &&\n"> <"\tcsha1=$(git rev-parse HEAD^{commit}) &&\n"> <"\tgit reset --hard HEAD^ &&\n"> <"\ttest_tick &&\n"> <"\tgit reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&\n"> <"\t# The pack-objects call on the next line is equivalent to\n"> <"\t# git repack -A -d without the call to prune-packed\n"> <"\tgit pack-objects --honor-pack-keep --non-empty --all --reflog \\\n"> <"\t --unpack-unreachable <"\trm -f .git/objects/pack/* &&\n"> <"\tmv pack-* .git/objects/pack/ &&\n"> <"\ttest 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |\n"> <"\t\tegrep \"^$csha1 \" | sort | uniq | wc -l) &&\n"> <"\techo > .git/objects/info/alternates &&\n"> <"\ttest_must_fail git show $csha1\n"> ) } ) (C {(test_expect_success)} {(SQ <"local packed unreachable obs that exist in alternate ODB are not loosened">)} { (SQ <"\n"> <"\techo $(pwd)/alt_objects > .git/objects/info/alternates &&\n"> <"\techo \"$csha1\" | git pack-objects --non-empty --all --reflog pack &&\n"> <"\trm -f .git/objects/pack/* &&\n"> <"\tmv pack-* .git/objects/pack/ &&\n"> <"\t# The pack-objects call on the next line is equivalent to\n"> <"\t# git repack -A -d without the call to prune-packed\n"> <"\tgit pack-objects --honor-pack-keep --non-empty --all --reflog \\\n"> <"\t --unpack-unreachable <"\trm -f .git/objects/pack/* &&\n"> <"\tmv pack-* .git/objects/pack/ &&\n"> <"\ttest 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |\n"> <"\t\tegrep \"^$csha1 \" | sort | uniq | wc -l) &&\n"> <"\techo > .git/objects/info/alternates &&\n"> <"\ttest_must_fail git show $csha1\n"> ) } ) (C {(test_expect_success)} {(SQ <"objects made unreachable by grafts only are kept">)} { (SQ <"\n"> <"\ttest_tick &&\n"> <"\tgit commit --allow-empty -m \"commit 4\" &&\n"> <"\tH0=$(git rev-parse HEAD) &&\n"> <"\tH1=$(git rev-parse HEAD^) &&\n"> <"\tH2=$(git rev-parse HEAD^^) &&\n"> <"\techo \"$H0 $H2\" > .git/info/grafts &&\n"> <"\tgit reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&\n"> <"\tgit repack -a -d &&\n"> <"\tgit cat-file -t $H1\n"> <"\t"> ) } ) (C {(test_done)}) ] )