Raw
1 #!/bin/sh
2
3 test_description='on-disk reverse index'
4
5 . ./test-lib.sh
6
7 # The below tests want control over the 'pack.writeReverseIndex' setting
8 # themselves to assert various combinations of it with other options.
9 sane_unset GIT_TEST_NO_WRITE_REV_INDEX
10
11 packdir=.git/objects/pack
12
13 test_expect_success 'setup' '
14 test_commit base &&
15
16 test_config pack.writeReverseIndex false &&
17 pack=$(git pack-objects --all $packdir/pack) &&
18 rev=$packdir/pack-$pack.rev &&
19
20 test_path_is_missing $rev
21 '
22
23 test_index_pack () {
24 rm -f $rev &&
25 conf=$1 &&
26 shift &&
27 # remove the index since Windows won't overwrite an existing file
28 rm $packdir/pack-$pack.idx &&
29 git -c pack.writeReverseIndex=$conf index-pack "$@" \
30 $packdir/pack-$pack.pack
31 }
32
33 test_expect_success 'index-pack with pack.writeReverseIndex' '
34 test_index_pack "" &&
35 test_path_is_missing $rev &&
36
37 test_index_pack false &&
38 test_path_is_missing $rev &&
39
40 test_index_pack true &&
41 test_path_is_file $rev
42 '
43
44 test_expect_success 'index-pack with --[no-]rev-index' '
45 for conf in "" true false
46 do
47 test_index_pack "$conf" --rev-index &&
48 test_path_exists $rev &&
49
50 test_index_pack "$conf" --no-rev-index &&
51 test_path_is_missing $rev || return 1
52 done
53 '
54
55 test_expect_success 'index-pack can verify reverse indexes' '
56 test_when_finished "rm -f $rev" &&
57 test_index_pack true &&
58
59 test_path_is_file $rev &&
60 git index-pack --rev-index --verify $packdir/pack-$pack.pack &&
61
62 # Intentionally corrupt the reverse index.
63 chmod u+w $rev &&
64 printf "xxxx" | dd of=$rev bs=1 count=4 conv=notrunc &&
65
66 test_must_fail git index-pack --rev-index --verify \
67 $packdir/pack-$pack.pack 2>err &&
68 test_grep "validation error" err
69 '
70
71 test_expect_success 'index-pack infers reverse index name with -o' '
72 git index-pack --rev-index -o other.idx $packdir/pack-$pack.pack &&
73 test_path_is_file other.idx &&
74 test_path_is_file other.rev
75 '
76
77 test_expect_success 'pack-objects respects pack.writeReverseIndex' '
78 test_when_finished "rm -fr pack-1-*" &&
79
80 git -c pack.writeReverseIndex= pack-objects --all pack-1 &&
81 test_path_is_missing pack-1-*.rev &&
82
83 git -c pack.writeReverseIndex=false pack-objects --all pack-1 &&
84 test_path_is_missing pack-1-*.rev &&
85
86 git -c pack.writeReverseIndex=true pack-objects --all pack-1 &&
87 test_path_is_file pack-1-*.rev
88 '
89
90 test_expect_success 'reverse index is not generated when available on disk' '
91 test_index_pack true &&
92 test_path_is_file $rev &&
93
94 git rev-parse HEAD >tip &&
95 GIT_TEST_REV_INDEX_DIE_IN_MEMORY=1 git cat-file \
96 --batch-check="%(objectsize:disk)" <tip
97 '
98
99 test_expect_success 'reverse index is ignored when pack.readReverseIndex is false' '
100 test_index_pack true &&
101 test_path_is_file $rev &&
102
103 test_config pack.readReverseIndex false &&
104
105 git rev-parse HEAD >tip &&
106 GIT_TEST_REV_INDEX_DIE_ON_DISK=1 git cat-file \
107 --batch-check="%(objectsize:disk)" <tip
108 '
109
110 test_expect_success 'revindex in-memory vs on-disk' '
111 git init repo &&
112 test_when_finished "rm -fr repo" &&
113 (
114 cd repo &&
115
116 test_commit commit &&
117
118 git rev-list --objects --no-object-names --all >objects &&
119
120 git -c pack.writeReverseIndex=false repack -ad &&
121 test_path_is_missing $packdir/pack-*.rev &&
122 git cat-file --batch-check="%(objectsize:disk) %(objectname)" \
123 <objects >in-core &&
124
125 git -c pack.writeReverseIndex=true repack -ad &&
126 test_path_is_file $packdir/pack-*.rev &&
127 git cat-file --batch-check="%(objectsize:disk) %(objectname)" \
128 <objects >on-disk &&
129
130 test_cmp on-disk in-core
131 )
132 '
133
134 test_expect_success 'fsck succeeds on good rev-index' '
135 test_when_finished rm -fr repo &&
136 git init repo &&
137 (
138 cd repo &&
139
140 test_commit commit &&
141 git -c pack.writeReverseIndex=true repack -ad &&
142 git fsck 2>err &&
143 test_must_be_empty err
144 )
145 '
146
147 test_expect_success 'set up rev-index corruption tests' '
148 git init corrupt &&
149 (
150 cd corrupt &&
151
152 test_commit commit &&
153 git -c pack.writeReverseIndex=true repack -ad &&
154
155 revfile=$(ls .git/objects/pack/pack-*.rev) &&
156 chmod a+w $revfile &&
157 cp $revfile $revfile.bak
158 )
159 '
160
161 corrupt_rev_and_verify () {
162 (
163 pos="$1" &&
164 value="$2" &&
165 error="$3" &&
166
167 cd corrupt &&
168 revfile=$(ls .git/objects/pack/pack-*.rev) &&
169
170 # Reset to original rev-file.
171 cp $revfile.bak $revfile &&
172
173 printf "$value" | dd of=$revfile bs=1 seek="$pos" conv=notrunc &&
174 test_must_fail git fsck 2>err &&
175 grep "$error" err
176 )
177 }
178
179 test_expect_success 'fsck catches invalid checksum' '
180 revfile=$(ls corrupt/.git/objects/pack/pack-*.rev) &&
181 orig_size=$(wc -c <$revfile) &&
182 hashpos=$((orig_size - 10)) &&
183 corrupt_rev_and_verify $hashpos bogus \
184 "invalid checksum"
185 '
186
187 test_expect_success 'fsck catches invalid row position' '
188 corrupt_rev_and_verify 14 "\07" \
189 "invalid rev-index position"
190 '
191
192 test_expect_success 'fsck catches invalid header: magic number' '
193 corrupt_rev_and_verify 1 "\07" \
194 "reverse-index file .* has unknown signature"
195 '
196
197 test_expect_success 'fsck catches invalid header: version' '
198 corrupt_rev_and_verify 7 "\02" \
199 "reverse-index file .* has unsupported version"
200 '
201
202 test_expect_success 'fsck catches invalid header: hash function' '
203 corrupt_rev_and_verify 11 "\03" \
204 "reverse-index file .* has unsupported hash id"
205 '
206
207 test_done