rebase: use correct base for --keep-base when a branch is given
[alt-git.git] / t / t5312-prune-corruption.sh
blob9d8e249ae8b7f38c4c941bd76ef904cdfe1b3d27
1 #!/bin/sh
3 test_description='
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-lib.sh
19 test_expect_success 'disable reflogs' '
20 git config core.logallrefupdates false &&
21 git reflog expire --expire=all --all
24 create_bogus_ref () {
25 test-tool ref-store main update-ref msg "refs/heads/bogus..name" $bogus $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
26 test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/bogus..name"
29 test_expect_success 'create history reachable only from a bogus-named ref' '
30 test_tick && git commit --allow-empty -m main &&
31 base=$(git rev-parse HEAD) &&
32 test_tick && git commit --allow-empty -m bogus &&
33 bogus=$(git rev-parse HEAD) &&
34 git cat-file commit $bogus >saved &&
35 git reset --hard HEAD^
38 test_expect_success 'pruning does not drop bogus object' '
39 test_when_finished "git hash-object -w -t commit saved" &&
40 create_bogus_ref &&
41 test_must_fail git prune --expire=now &&
42 git cat-file -e $bogus
45 test_expect_success 'put bogus object into pack' '
46 git tag reachable $bogus &&
47 git repack -ad &&
48 git tag -d reachable &&
49 git cat-file -e $bogus
52 test_expect_success 'non-destructive repack bails on bogus ref' '
53 create_bogus_ref &&
54 test_must_fail git repack -adk
57 test_expect_success 'GIT_REF_PARANOIA=0 overrides safety' '
58 create_bogus_ref &&
59 GIT_REF_PARANOIA=0 git repack -adk
63 test_expect_success 'destructive repack keeps packed object' '
64 create_bogus_ref &&
65 test_must_fail git repack -Ad --unpack-unreachable=now &&
66 git cat-file -e $bogus &&
67 test_must_fail git repack -ad &&
68 git cat-file -e $bogus
71 test_expect_success 'destructive repack not confused by dangling symref' '
72 test_when_finished "git symbolic-ref -d refs/heads/dangling" &&
73 git symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&
74 git repack -ad &&
75 test_must_fail git cat-file -e $bogus
78 # We create two new objects here, "one" and "two". Our
79 # main branch points to "two", which is deleted,
80 # corrupting the repository. But we'd like to make sure
81 # that the otherwise unreachable "one" is not pruned
82 # (since it is the user's best bet for recovering
83 # from the corruption).
85 # Note that we also point HEAD somewhere besides "two",
86 # as we want to make sure we test the case where we
87 # pick up the reference to "two" by iterating the refs,
88 # not by resolving HEAD.
89 test_expect_success 'create history with missing tip commit' '
90 test_tick && git commit --allow-empty -m one &&
91 recoverable=$(git rev-parse HEAD) &&
92 git cat-file commit $recoverable >saved &&
93 test_tick && git commit --allow-empty -m two &&
94 missing=$(git rev-parse HEAD) &&
95 git checkout --detach $base &&
96 rm .git/objects/$(echo $missing | sed "s,..,&/,") &&
97 test_must_fail git cat-file -e $missing
100 test_expect_success 'pruning with a corrupted tip does not drop history' '
101 test_when_finished "git hash-object -w -t commit saved" &&
102 test_must_fail git prune --expire=now &&
103 git cat-file -e $recoverable
106 test_expect_success 'pack-refs does not silently delete broken loose ref' '
107 git pack-refs --all --prune &&
108 echo $missing >expect &&
109 git rev-parse refs/heads/main >actual &&
110 test_cmp expect actual
113 # we do not want to count on running pack-refs to
114 # actually pack it, as it is perfectly reasonable to
115 # skip processing a broken ref
116 test_expect_success REFFILES 'create packed-refs file with broken ref' '
117 rm -f .git/refs/heads/main &&
118 cat >.git/packed-refs <<-EOF &&
119 $missing refs/heads/main
120 $recoverable refs/heads/other
122 echo $missing >expect &&
123 git rev-parse refs/heads/main >actual &&
124 test_cmp expect actual
127 test_expect_success REFFILES 'pack-refs does not silently delete broken packed ref' '
128 git pack-refs --all --prune &&
129 git rev-parse refs/heads/main >actual &&
130 test_cmp expect actual
133 test_expect_success REFFILES 'pack-refs does not drop broken refs during deletion' '
134 git update-ref -d refs/heads/other &&
135 git rev-parse refs/heads/main >actual &&
136 test_cmp expect actual
139 test_done