t / t7700-repack.shon commit Merge branch 'md/filter-trees' (77d5037)
   1#!/bin/sh
   2
   3test_description='git repack works correctly'
   4
   5. ./test-lib.sh
   6
   7commit_and_pack() {
   8        test_commit "$@" >/dev/null &&
   9        SHA1=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) &&
  10        echo pack-${SHA1}.pack
  11}
  12
  13test_expect_success 'objects in packs marked .keep are not repacked' '
  14        echo content1 > file1 &&
  15        echo content2 > file2 &&
  16        git add . &&
  17        test_tick &&
  18        git commit -m initial_commit &&
  19        # Create two packs
  20        # The first pack will contain all of the objects except one
  21        git rev-list --objects --all | grep -v file2 |
  22                git pack-objects pack > /dev/null &&
  23        # The second pack will contain the excluded object
  24        packsha1=$(git rev-list --objects --all | grep file2 |
  25                git pack-objects pack) &&
  26        >pack-$packsha1.keep &&
  27        objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
  28                sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
  29        mv pack-* .git/objects/pack/ &&
  30        git repack -A -d -l &&
  31        git prune-packed &&
  32        for p in .git/objects/pack/*.idx; do
  33                idx=$(basename $p)
  34                test "pack-$packsha1.idx" = "$idx" && continue
  35                if git verify-pack -v $p | egrep "^$objsha1"; then
  36                        found_duplicate_object=1
  37                        echo "DUPLICATE OBJECT FOUND"
  38                        break
  39                fi
  40        done &&
  41        test -z "$found_duplicate_object"
  42'
  43
  44test_expect_success 'writing bitmaps via command-line can duplicate .keep objects' '
  45        # build on $objsha1, $packsha1, and .keep state from previous
  46        git repack -Adbl &&
  47        test_when_finished "found_duplicate_object=" &&
  48        for p in .git/objects/pack/*.idx; do
  49                idx=$(basename $p)
  50                test "pack-$packsha1.idx" = "$idx" && continue
  51                if git verify-pack -v $p | egrep "^$objsha1"; then
  52                        found_duplicate_object=1
  53                        echo "DUPLICATE OBJECT FOUND"
  54                        break
  55                fi
  56        done &&
  57        test "$found_duplicate_object" = 1
  58'
  59
  60test_expect_success 'writing bitmaps via config can duplicate .keep objects' '
  61        # build on $objsha1, $packsha1, and .keep state from previous
  62        git -c repack.writebitmaps=true repack -Adl &&
  63        test_when_finished "found_duplicate_object=" &&
  64        for p in .git/objects/pack/*.idx; do
  65                idx=$(basename $p)
  66                test "pack-$packsha1.idx" = "$idx" && continue
  67                if git verify-pack -v $p | egrep "^$objsha1"; then
  68                        found_duplicate_object=1
  69                        echo "DUPLICATE OBJECT FOUND"
  70                        break
  71                fi
  72        done &&
  73        test "$found_duplicate_object" = 1
  74'
  75
  76test_expect_success 'loose objects in alternate ODB are not repacked' '
  77        mkdir alt_objects &&
  78        echo $(pwd)/alt_objects > .git/objects/info/alternates &&
  79        echo content3 > file3 &&
  80        objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&
  81        git add file3 &&
  82        test_tick &&
  83        git commit -m commit_file3 &&
  84        git repack -a -d -l &&
  85        git prune-packed &&
  86        for p in .git/objects/pack/*.idx; do
  87                if git verify-pack -v $p | egrep "^$objsha1"; then
  88                        found_duplicate_object=1
  89                        echo "DUPLICATE OBJECT FOUND"
  90                        break
  91                fi
  92        done &&
  93        test -z "$found_duplicate_object"
  94'
  95
  96test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' '
  97        mkdir alt_objects/pack &&
  98        mv .git/objects/pack/* alt_objects/pack &&
  99        git repack -a &&
 100        myidx=$(ls -1 .git/objects/pack/*.idx) &&
 101        test -f "$myidx" &&
 102        for p in alt_objects/pack/*.idx; do
 103                git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
 104        done | while read sha1 rest; do
 105                if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
 106                        echo "Missing object in local pack: $sha1"
 107                        return 1
 108                fi
 109        done
 110'
 111
 112test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' '
 113        rm -f .git/objects/pack/* &&
 114        echo new_content >> file1 &&
 115        git add file1 &&
 116        test_tick &&
 117        git commit -m more_content &&
 118        git repack &&
 119        git repack -a -d &&
 120        myidx=$(ls -1 .git/objects/pack/*.idx) &&
 121        test -f "$myidx" &&
 122        for p in alt_objects/pack/*.idx; do
 123                git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
 124        done | while read sha1 rest; do
 125                if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
 126                        echo "Missing object in local pack: $sha1"
 127                        return 1
 128                fi
 129        done
 130'
 131
 132test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
 133        # swap the .keep so the commit object is in the pack with .keep
 134        for p in alt_objects/pack/*.pack
 135        do
 136                base_name=$(basename $p .pack) &&
 137                if test -f alt_objects/pack/$base_name.keep
 138                then
 139                        rm alt_objects/pack/$base_name.keep
 140                else
 141                        touch alt_objects/pack/$base_name.keep
 142                fi
 143        done &&
 144        git repack -a -d &&
 145        myidx=$(ls -1 .git/objects/pack/*.idx) &&
 146        test -f "$myidx" &&
 147        for p in alt_objects/pack/*.idx; do
 148                git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
 149        done | while read sha1 rest; do
 150                if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
 151                        echo "Missing object in local pack: $sha1"
 152                        return 1
 153                fi
 154        done
 155'
 156
 157test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
 158        rm -f alt_objects/pack/*.keep &&
 159        mv .git/objects/pack/* alt_objects/pack/ &&
 160        csha1=$(git rev-parse HEAD^{commit}) &&
 161        git reset --hard HEAD^ &&
 162        test_tick &&
 163        git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
 164        # The pack-objects call on the next line is equivalent to
 165        # git repack -A -d without the call to prune-packed
 166        git pack-objects --honor-pack-keep --non-empty --all --reflog \
 167            --unpack-unreachable </dev/null pack &&
 168        rm -f .git/objects/pack/* &&
 169        mv pack-* .git/objects/pack/ &&
 170        test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
 171                egrep "^$csha1 " | sort | uniq | wc -l) &&
 172        echo > .git/objects/info/alternates &&
 173        test_must_fail git show $csha1
 174'
 175
 176test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
 177        echo $(pwd)/alt_objects > .git/objects/info/alternates &&
 178        echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
 179        rm -f .git/objects/pack/* &&
 180        mv pack-* .git/objects/pack/ &&
 181        # The pack-objects call on the next line is equivalent to
 182        # git repack -A -d without the call to prune-packed
 183        git pack-objects --honor-pack-keep --non-empty --all --reflog \
 184            --unpack-unreachable </dev/null pack &&
 185        rm -f .git/objects/pack/* &&
 186        mv pack-* .git/objects/pack/ &&
 187        test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
 188                egrep "^$csha1 " | sort | uniq | wc -l) &&
 189        echo > .git/objects/info/alternates &&
 190        test_must_fail git show $csha1
 191'
 192
 193test_expect_success 'objects made unreachable by grafts only are kept' '
 194        test_tick &&
 195        git commit --allow-empty -m "commit 4" &&
 196        H0=$(git rev-parse HEAD) &&
 197        H1=$(git rev-parse HEAD^) &&
 198        H2=$(git rev-parse HEAD^^) &&
 199        echo "$H0 $H2" > .git/info/grafts &&
 200        git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
 201        git repack -a -d &&
 202        git cat-file -t $H1
 203'
 204
 205test_expect_success 'repack --keep-pack' '
 206        test_create_repo keep-pack &&
 207        (
 208                cd keep-pack &&
 209                P1=$(commit_and_pack 1) &&
 210                P2=$(commit_and_pack 2) &&
 211                P3=$(commit_and_pack 3) &&
 212                P4=$(commit_and_pack 4) &&
 213                ls .git/objects/pack/*.pack >old-counts &&
 214                test_line_count = 4 old-counts &&
 215                git repack -a -d --keep-pack $P1 --keep-pack $P4 &&
 216                ls .git/objects/pack/*.pack >new-counts &&
 217                grep -q $P1 new-counts &&
 218                grep -q $P4 new-counts &&
 219                test_line_count = 3 new-counts &&
 220                git fsck
 221        )
 222'
 223
 224test_done
 225