blob: ea889c088a51f635e1e111f1e55d02cd21b53d0f [file] [log] [blame]
Jeff King8b43fb12015-03-20 14:43:02 -04001#!/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.
Jeff King5b062e12021-09-24 14:37:11 -040010
11Note that we do assert command failure in these cases, because that is
12what currently happens. If that changes, these tests should be revisited.
Jeff King8b43fb12015-03-20 14:43:02 -040013'
Johannes Schindelin966b4be2020-11-18 23:44:29 +000014GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
Johannes Schindelin334afbc2020-11-18 23:44:19 +000015export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
16
Jeff King8b43fb12015-03-20 14:43:02 -040017. ./test-lib.sh
18
19test_expect_success 'disable reflogs' '
20 git config core.logallrefupdates false &&
David Turnerd0ab0582015-07-27 18:57:08 -040021 git reflog expire --expire=all --all
Jeff King8b43fb12015-03-20 14:43:02 -040022'
23
Jeff Kingf8058442021-09-24 14:36:18 -040024create_bogus_ref () {
25 test_when_finished 'rm -f .git/refs/heads/bogus..name' &&
26 echo $bogus >.git/refs/heads/bogus..name
27}
28
Jeff King8b43fb12015-03-20 14:43:02 -040029test_expect_success 'create history reachable only from a bogus-named ref' '
Johannes Schindelin966b4be2020-11-18 23:44:29 +000030 test_tick && git commit --allow-empty -m main &&
Jeff King8b43fb12015-03-20 14:43:02 -040031 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 &&
Jeff King8b43fb12015-03-20 14:43:02 -040035 git reset --hard HEAD^
36'
37
Jeff Kingff4056b2015-03-20 14:43:09 -040038test_expect_success 'pruning does not drop bogus object' '
Jeff King8b43fb12015-03-20 14:43:02 -040039 test_when_finished "git hash-object -w -t commit saved" &&
Jeff Kingf8058442021-09-24 14:36:18 -040040 create_bogus_ref &&
Jeff King5b062e12021-09-24 14:37:11 -040041 test_must_fail git prune --expire=now &&
Jeff King2ac0cbc2021-09-24 14:35:29 -040042 git cat-file -e $bogus
Jeff King8b43fb12015-03-20 14:43:02 -040043'
44
45test_expect_success 'put bogus object into pack' '
46 git tag reachable $bogus &&
47 git repack -ad &&
48 git tag -d reachable &&
Jeff King2ac0cbc2021-09-24 14:35:29 -040049 git cat-file -e $bogus
Jeff King8b43fb12015-03-20 14:43:02 -040050'
51
Jeff King968f12f2021-09-24 14:46:13 -040052test_expect_success 'non-destructive repack bails on bogus ref' '
Jeff King078eecb2021-09-24 14:36:42 -040053 create_bogus_ref &&
Jeff King968f12f2021-09-24 14:46:13 -040054 test_must_fail git repack -adk
Jeff King078eecb2021-09-24 14:36:42 -040055'
56
Jeff King968f12f2021-09-24 14:46:13 -040057test_expect_success 'GIT_REF_PARANOIA=0 overrides safety' '
58 create_bogus_ref &&
59 GIT_REF_PARANOIA=0 git repack -adk
60'
61
62
Jeff King8d422992015-03-20 14:43:13 -040063test_expect_success 'destructive repack keeps packed object' '
Jeff Kingf8058442021-09-24 14:36:18 -040064 create_bogus_ref &&
Jeff King5b062e12021-09-24 14:37:11 -040065 test_must_fail git repack -Ad --unpack-unreachable=now &&
Jeff King2ac0cbc2021-09-24 14:35:29 -040066 git cat-file -e $bogus &&
Jeff King5b062e12021-09-24 14:37:11 -040067 test_must_fail git repack -ad &&
Jeff King2ac0cbc2021-09-24 14:35:29 -040068 git cat-file -e $bogus
Jeff King8b43fb12015-03-20 14:43:02 -040069'
70
Jeff King6d751be2021-09-24 14:42:38 -040071test_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
76'
77
Jeff King8b43fb12015-03-20 14:43:02 -040078# We create two new objects here, "one" and "two". Our
Johannes Schindelin966b4be2020-11-18 23:44:29 +000079# main branch points to "two", which is deleted,
Jeff King8b43fb12015-03-20 14:43:02 -040080# 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).
84#
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.
89test_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
98'
99
Jeff Kingff4056b2015-03-20 14:43:09 -0400100test_expect_success 'pruning with a corrupted tip does not drop history' '
Jeff King8b43fb12015-03-20 14:43:02 -0400101 test_when_finished "git hash-object -w -t commit saved" &&
Jeff King5b062e12021-09-24 14:37:11 -0400102 test_must_fail git prune --expire=now &&
Jeff King2ac0cbc2021-09-24 14:35:29 -0400103 git cat-file -e $recoverable
Jeff King8b43fb12015-03-20 14:43:02 -0400104'
105
106test_expect_success 'pack-refs does not silently delete broken loose ref' '
107 git pack-refs --all --prune &&
108 echo $missing >expect &&
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000109 git rev-parse refs/heads/main >actual &&
Jeff King8b43fb12015-03-20 14:43:02 -0400110 test_cmp expect actual
111'
112
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
116test_expect_success 'create packed-refs file with broken ref' '
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000117 rm -f .git/refs/heads/main &&
Jeff King8b43fb12015-03-20 14:43:02 -0400118 cat >.git/packed-refs <<-EOF &&
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000119 $missing refs/heads/main
Jeff King8b43fb12015-03-20 14:43:02 -0400120 $recoverable refs/heads/other
121 EOF
122 echo $missing >expect &&
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000123 git rev-parse refs/heads/main >actual &&
Jeff King8b43fb12015-03-20 14:43:02 -0400124 test_cmp expect actual
125'
126
127test_expect_success 'pack-refs does not silently delete broken packed ref' '
128 git pack-refs --all --prune &&
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000129 git rev-parse refs/heads/main >actual &&
Jeff King8b43fb12015-03-20 14:43:02 -0400130 test_cmp expect actual
131'
132
Jeff Kingea56c4e2015-03-20 14:43:17 -0400133test_expect_success 'pack-refs does not drop broken refs during deletion' '
Jeff King8b43fb12015-03-20 14:43:02 -0400134 git update-ref -d refs/heads/other &&
Johannes Schindelin966b4be2020-11-18 23:44:29 +0000135 git rev-parse refs/heads/main >actual &&
Jeff King8b43fb12015-03-20 14:43:02 -0400136 test_cmp expect actual
137'
138
139test_done