4 Test pruning of repositories with minor corruptions. The goal
5 here is that we should always be erring on the side of safety. So
6 if we see, for example, a ref with a bogus name, it is OK either to
7 bail out or to proceed using it as a reachable tip, but it is _not_
8 OK to proceed as if it did not exist. Otherwise we might silently
9 delete objects that cannot be recovered.
11 Note that we do assert command failure in these cases, because that is
12 what currently happens. If that changes, these tests should be revisited.
14 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
15 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
17 TEST_PASSES_SANITIZE_LEAK
=true
20 test_expect_success
'disable reflogs' '
21 git config core.logallrefupdates false &&
22 git reflog expire --expire=all --all
26 test-tool ref-store main update-ref msg
"refs/heads/bogus..name" $bogus $ZERO_OID REF_SKIP_REFNAME_VERIFICATION
&&
27 test_when_finished
"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/bogus..name"
30 test_expect_success
'create history reachable only from a bogus-named ref' '
31 test_tick && git commit --allow-empty -m main &&
32 base=$(git rev-parse HEAD) &&
33 test_tick && git commit --allow-empty -m bogus &&
34 bogus=$(git rev-parse HEAD) &&
35 git cat-file commit $bogus >saved &&
36 git reset --hard HEAD^
39 test_expect_success
'pruning does not drop bogus object' '
40 test_when_finished "git hash-object -w -t commit saved" &&
42 test_must_fail git prune --expire=now &&
43 git cat-file -e $bogus
46 test_expect_success
'put bogus object into pack' '
47 git tag reachable $bogus &&
49 git tag -d reachable &&
50 git cat-file -e $bogus
53 test_expect_success
'non-destructive repack bails on bogus ref' '
55 test_must_fail git repack -adk
58 test_expect_success
'GIT_REF_PARANOIA=0 overrides safety' '
60 GIT_REF_PARANOIA=0 git repack -adk
64 test_expect_success
'destructive repack keeps packed object' '
66 test_must_fail git repack -Ad --unpack-unreachable=now &&
67 git cat-file -e $bogus &&
68 test_must_fail git repack -ad &&
69 git cat-file -e $bogus
72 test_expect_success
'destructive repack not confused by dangling symref' '
73 test_when_finished "git symbolic-ref -d refs/heads/dangling" &&
74 git symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&
76 test_must_fail git cat-file -e $bogus
79 # We create two new objects here, "one" and "two". Our
80 # main branch points to "two", which is deleted,
81 # corrupting the repository. But we'd like to make sure
82 # that the otherwise unreachable "one" is not pruned
83 # (since it is the user's best bet for recovering
84 # from the corruption).
86 # Note that we also point HEAD somewhere besides "two",
87 # as we want to make sure we test the case where we
88 # pick up the reference to "two" by iterating the refs,
89 # not by resolving HEAD.
90 test_expect_success
'create history with missing tip commit' '
91 test_tick && git commit --allow-empty -m one &&
92 recoverable=$(git rev-parse HEAD) &&
93 git cat-file commit $recoverable >saved &&
94 test_tick && git commit --allow-empty -m two &&
95 missing=$(git rev-parse HEAD) &&
96 git checkout --detach $base &&
97 rm .git/objects/$(echo $missing | sed "s,..,&/,") &&
98 test_must_fail git cat-file -e $missing
101 test_expect_success
'pruning with a corrupted tip does not drop history' '
102 test_when_finished "git hash-object -w -t commit saved" &&
103 test_must_fail git prune --expire=now &&
104 git cat-file -e $recoverable
107 test_expect_success
'pack-refs does not silently delete broken loose ref' '
108 git pack-refs --all --prune &&
109 echo $missing >expect &&
110 git rev-parse refs/heads/main >actual &&
111 test_cmp expect actual
114 # we do not want to count on running pack-refs to
115 # actually pack it, as it is perfectly reasonable to
116 # skip processing a broken ref
117 test_expect_success REFFILES
'create packed-refs file with broken ref' '
118 rm -f .git/refs/heads/main &&
119 cat >.git/packed-refs <<-EOF &&
120 $missing refs/heads/main
121 $recoverable refs/heads/other
123 echo $missing >expect &&
124 git rev-parse refs/heads/main >actual &&
125 test_cmp expect actual
128 test_expect_success REFFILES
'pack-refs does not silently delete broken packed ref' '
129 git pack-refs --all --prune &&
130 git rev-parse refs/heads/main >actual &&
131 test_cmp expect actual
134 test_expect_success REFFILES
'pack-refs does not drop broken refs during deletion' '
135 git update-ref -d refs/heads/other &&
136 git rev-parse refs/heads/main >actual &&
137 test_cmp expect actual