1#!/bin/sh 2 3test_description=' 4Test pruning of repositories with minor corruptions. The goal 5here is that we should always be erring on the side of safety. So 6if we see, for example, a ref with a bogus name, it is OK either to 7bail out or to proceed using it as a reachable tip, but it is _not_ 8OK to proceed as if it did not exist. Otherwise we might silently 9delete objects that cannot be recovered. 10' 11. ./test-lib.sh 12 13test_expect_success 'disable reflogs'' 14 git config core.logallrefupdates false && 15 rm -rf .git/logs 16' 17 18test_expect_success 'create history reachable only from a bogus-named ref'' 19 test_tick && git commit --allow-empty -m master && 20 base=$(git rev-parse HEAD)&& 21 test_tick && git commit --allow-empty -m bogus && 22 bogus=$(git rev-parse HEAD)&& 23 git cat-file commit$bogus>saved && 24 echo$bogus>.git/refs/heads/bogus..name && 25 git reset --hard HEAD^ 26' 27 28test_expect_success 'pruning does not drop bogus object'' 29 test_when_finished "git hash-object -w -t commit saved" && 30 test_might_fail git prune --expire=now && 31 verbose git cat-file -e$bogus 32' 33 34test_expect_success 'put bogus object into pack'' 35 git tag reachable$bogus&& 36 git repack -ad && 37 git tag -d reachable && 38 verbose git cat-file -e$bogus 39' 40 41test_expect_success 'destructive repack keeps packed object'' 42 test_might_fail git repack -Ad --unpack-unreachable=now && 43 verbose git cat-file -e$bogus&& 44 test_might_fail git repack -ad && 45 verbose git cat-file -e$bogus 46' 47 48# subsequent tests will have different corruptions 49test_expect_success 'clean up bogus ref'' 50 rm .git/refs/heads/bogus..name 51' 52 53# We create two new objects here, "one" and "two". Our 54# master branch points to "two", which is deleted, 55# corrupting the repository. But we'd like to make sure 56# that the otherwise unreachable "one" is not pruned 57# (since it is the user's best bet for recovering 58# from the corruption). 59# 60# Note that we also point HEAD somewhere besides "two", 61# as we want to make sure we test the case where we 62# pick up the reference to "two" by iterating the refs, 63# not by resolving HEAD. 64test_expect_success 'create history with missing tip commit'' 65 test_tick && git commit --allow-empty -m one && 66 recoverable=$(git rev-parse HEAD)&& 67 git cat-file commit$recoverable>saved && 68 test_tick && git commit --allow-empty -m two && 69 missing=$(git rev-parse HEAD)&& 70 git checkout --detach$base&& 71 rm .git/objects/$(echo $missing | sed "s,..,&/,")&& 72 test_must_fail git cat-file -e$missing 73' 74 75test_expect_success 'pruning with a corrupted tip does not drop history'' 76 test_when_finished "git hash-object -w -t commit saved" && 77 test_might_fail git prune --expire=now && 78 verbose git cat-file -e$recoverable 79' 80 81test_expect_success 'pack-refs does not silently delete broken loose ref'' 82 git pack-refs --all --prune && 83 echo$missing>expect && 84 git rev-parse refs/heads/master >actual && 85 test_cmp expect actual 86' 87 88# we do not want to count on running pack-refs to 89# actually pack it, as it is perfectly reasonable to 90# skip processing a broken ref 91test_expect_success 'create packed-refs file with broken ref'' 92 rm -f .git/refs/heads/master && 93 cat >.git/packed-refs <<-EOF && 94$missingrefs/heads/master 95$recoverablerefs/heads/other 96 EOF 97 echo$missing>expect && 98 git rev-parse refs/heads/master >actual && 99 test_cmp expect actual 100' 101 102test_expect_success 'pack-refs does not silently delete broken packed ref'' 103 git pack-refs --all --prune && 104 git rev-parse refs/heads/master >actual && 105 test_cmp expect actual 106' 107 108test_expect_success 'pack-refs does not drop broken refs during deletion'' 109 git update-ref -d refs/heads/other && 110 git rev-parse refs/heads/master >actual && 111 test_cmp expect actual 112' 113 114test_done