Raw
1 #!/bin/sh
2
3 test_description='fetch/receive strict mode'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8
9 test_expect_success 'setup and inject "corrupt or missing" object' '
10 echo hello >greetings &&
11 git add greetings &&
12 git commit -m greetings &&
13
14 S=$(git rev-parse :greetings | sed -e "s|^..|&/|") &&
15 X=$(echo bye | git hash-object -w --stdin | sed -e "s|^..|&/|") &&
16 echo $S >S &&
17 echo $X >X &&
18 cp .git/objects/$S .git/objects/$S.back &&
19 mv -f .git/objects/$X .git/objects/$S &&
20
21 test_must_fail git fsck
22 '
23
24 test_expect_success 'fetch without strict' '
25 rm -rf dst &&
26 git init dst &&
27 (
28 cd dst &&
29 git config fetch.fsckobjects false &&
30 git config transfer.fsckobjects false &&
31 test_must_fail git fetch ../.git main
32 )
33 '
34
35 test_expect_success 'fetch with !fetch.fsckobjects' '
36 rm -rf dst &&
37 git init dst &&
38 (
39 cd dst &&
40 git config fetch.fsckobjects false &&
41 git config transfer.fsckobjects true &&
42 test_must_fail git fetch ../.git main
43 )
44 '
45
46 test_expect_success 'fetch with fetch.fsckobjects' '
47 rm -rf dst &&
48 git init dst &&
49 (
50 cd dst &&
51 git config fetch.fsckobjects true &&
52 git config transfer.fsckobjects false &&
53 test_must_fail git fetch ../.git main
54 )
55 '
56
57 test_expect_success 'fetch with transfer.fsckobjects' '
58 rm -rf dst &&
59 git init dst &&
60 (
61 cd dst &&
62 git config transfer.fsckobjects true &&
63 test_must_fail git fetch ../.git main
64 )
65 '
66
67 test_expect_success 'push without strict' '
68 rm -rf dst &&
69 git init dst &&
70 (
71 cd dst &&
72 git config fetch.fsckobjects false &&
73 git config transfer.fsckobjects false
74 ) &&
75 cat >exp <<-\EOF &&
76 To dst
77 ! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects)
78 Done
79 EOF
80 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
81 test_cmp exp act
82 '
83
84 test_expect_success 'push with !receive.fsckobjects' '
85 rm -rf dst &&
86 git init dst &&
87 (
88 cd dst &&
89 git config receive.fsckobjects false &&
90 git config transfer.fsckobjects true
91 ) &&
92 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
93 test_cmp exp act
94 '
95
96 test_expect_success 'push with receive.fsckobjects' '
97 rm -rf dst &&
98 git init dst &&
99 (
100 cd dst &&
101 git config receive.fsckobjects true &&
102 git config transfer.fsckobjects false
103 ) &&
104 cat >exp <<-\EOF &&
105 To dst
106 ! refs/heads/main:refs/heads/test [remote rejected] (unpacker error)
107 EOF
108 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
109 test_cmp exp act
110 '
111
112 test_expect_success 'push with transfer.fsckobjects' '
113 rm -rf dst &&
114 git init dst &&
115 (
116 cd dst &&
117 git config transfer.fsckobjects true
118 ) &&
119 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
120 test_cmp exp act
121 '
122
123 test_expect_success 'repair the "corrupt or missing" object' '
124 mv -f .git/objects/$(cat S) .git/objects/$(cat X) &&
125 mv .git/objects/$(cat S).back .git/objects/$(cat S) &&
126 rm -rf .git/objects/$(cat X) &&
127 git fsck
128 '
129
130 test_expect_success 'setup bogus commit' '
131 cat >bogus-commit <<-EOF &&
132 tree $EMPTY_TREE
133 author Bugs Bunny 1234567890 +0000
134 committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000
135
136 This commit object intentionally broken
137 EOF
138 commit="$(git hash-object --literally -t commit -w --stdin <bogus-commit)"
139 '
140
141 test_expect_success 'fsck with no skipList input' '
142 test_must_fail git fsck 2>err &&
143 test_grep "missingEmail" err
144 '
145
146 test_expect_success 'setup sorted and unsorted skipLists' '
147 cat >SKIP.unsorted <<-EOF &&
148 $(test_oid 004)
149 $(test_oid 002)
150 $commit
151 $(test_oid 001)
152 $(test_oid 003)
153 EOF
154 sort SKIP.unsorted >SKIP.sorted
155 '
156
157 test_expect_success 'fsck with sorted skipList' '
158 git -c fsck.skipList=SKIP.sorted fsck
159 '
160
161 test_expect_success 'fsck with unsorted skipList' '
162 git -c fsck.skipList=SKIP.unsorted fsck
163 '
164
165 test_expect_success 'fsck with invalid or bogus skipList input' '
166 git -c fsck.skipList=/dev/null -c fsck.missingEmail=ignore fsck &&
167 test_must_fail git -c fsck.skipList -c fsck.missingEmail=ignore fsck 2>err &&
168 test_grep "unable to parse '\'fsck.skiplist\'' from command-line config" err &&
169 test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err &&
170 test_grep "could not open.*: does-not-exist" err &&
171 test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err &&
172 test_grep "invalid object name: " err
173 '
174
175 test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' '
176 cat >SKIP.with-comment <<-EOF &&
177 # Some bad commit
178 $(test_oid 001)
179 EOF
180 test_must_fail git -c fsck.skipList=SKIP.with-comment fsck 2>err-with-comment &&
181 test_grep "missingEmail" err-with-comment &&
182 cat >SKIP.with-empty-line <<-EOF &&
183 $(test_oid 001)
184
185 $(test_oid 002)
186 EOF
187 test_must_fail git -c fsck.skipList=SKIP.with-empty-line fsck 2>err-with-empty-line &&
188 test_grep "missingEmail" err-with-empty-line
189 '
190
191 test_expect_success 'fsck no garbage output from comments & empty lines errors' '
192 test_line_count = 1 err-with-comment &&
193 test_line_count = 1 err-with-empty-line
194 '
195
196 test_expect_success 'fsck with invalid abbreviated skipList input' '
197 echo $commit | test_copy_bytes 20 >SKIP.abbreviated &&
198 test_must_fail git -c fsck.skipList=SKIP.abbreviated fsck 2>err-abbreviated &&
199 test_grep "^fatal: invalid object name: " err-abbreviated
200 '
201
202 test_expect_success 'fsck with exhaustive accepted skipList input (various types of comments etc.)' '
203 >SKIP.exhaustive &&
204 echo "# A commented line" >>SKIP.exhaustive &&
205 echo "" >>SKIP.exhaustive &&
206 echo " " >>SKIP.exhaustive &&
207 echo " # Comment after whitespace" >>SKIP.exhaustive &&
208 echo "$commit # Our bad commit (with leading whitespace and trailing comment)" >>SKIP.exhaustive &&
209 echo "# Some bad commit (leading whitespace)" >>SKIP.exhaustive &&
210 echo " $(test_oid 001)" >>SKIP.exhaustive &&
211 git -c fsck.skipList=SKIP.exhaustive fsck 2>err &&
212 test_must_be_empty err
213 '
214
215 test_expect_success 'receive-pack with missing receive.fsck.skipList path' '
216 test_must_fail git -c receive.fsck.skipList receive-pack dst 2>err &&
217 test_grep "unable to parse '\'receive.fsck.skiplist\'' from command-line config" err
218 '
219
220 test_expect_success 'push with receive.fsck.skipList' '
221 git push . $commit:refs/heads/bogus &&
222 rm -rf dst &&
223 git init dst &&
224 git --git-dir=dst/.git config receive.fsckObjects true &&
225 test_must_fail git push --porcelain dst bogus &&
226 echo $commit >dst/.git/SKIP &&
227
228 # receive.fsck.* does not fall back on fsck.*
229 git --git-dir=dst/.git config fsck.skipList SKIP &&
230 test_must_fail git push --porcelain dst bogus &&
231
232 # Invalid and/or bogus skipList input
233 git --git-dir=dst/.git config receive.fsck.skipList /dev/null &&
234 test_must_fail git push --porcelain dst bogus &&
235 git --git-dir=dst/.git config receive.fsck.skipList does-not-exist &&
236 test_must_fail git push --porcelain dst bogus 2>err &&
237 test_grep "could not open.*: does-not-exist" err &&
238 git --git-dir=dst/.git config receive.fsck.skipList config &&
239 test_must_fail git push --porcelain dst bogus 2>err &&
240 test_grep "invalid object name: " err &&
241
242 git --git-dir=dst/.git config receive.fsck.skipList SKIP &&
243 git push --porcelain dst bogus
244 '
245
246 test_expect_success 'fetch with fetch.fsck.skipList' '
247 refspec=refs/heads/bogus:refs/heads/bogus &&
248 git push . $commit:refs/heads/bogus &&
249 rm -rf dst &&
250 git init dst &&
251 git --git-dir=dst/.git config fetch.fsckObjects true &&
252 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
253 git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
254 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
255 echo $commit >dst/.git/SKIP &&
256
257 # fetch.fsck.* does not fall back on fsck.*
258 git --git-dir=dst/.git config fsck.skipList dst/.git/SKIP &&
259 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
260
261 # Invalid and/or bogus skipList input
262 test_must_fail git --git-dir=dst/.git -c fetch.fsck.skipList fetch \
263 "file://$(pwd)" $refspec 2>err &&
264 test_grep "unable to parse '\'fetch.fsck.skiplist\'' from command-line config" err &&
265 git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
266 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
267 git --git-dir=dst/.git config fetch.fsck.skipList does-not-exist &&
268 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
269 test_grep "could not open.*: does-not-exist" err &&
270 git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config &&
271 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
272 test_grep "invalid object name: " err &&
273
274 git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP &&
275 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec
276 '
277
278 test_expect_success 'fsck.<unknownmsg-id> dies' '
279 test_must_fail git -c fsck.whatEver=ignore fsck 2>err &&
280 test_grep "Unhandled message id: whatever" err
281 '
282
283 test_expect_success 'push with receive.fsck.missingEmail=warn' '
284 git push . $commit:refs/heads/bogus &&
285 rm -rf dst &&
286 git init dst &&
287 git --git-dir=dst/.git config receive.fsckobjects true &&
288 test_must_fail git push --porcelain dst bogus &&
289
290 # receive.fsck.<msg-id> does not fall back on fsck.<msg-id>
291 git --git-dir=dst/.git config fsck.missingEmail warn &&
292 test_must_fail git push --porcelain dst bogus &&
293
294 # receive.fsck.<unknownmsg-id> warns
295 git --git-dir=dst/.git config \
296 receive.fsck.whatEver error &&
297
298 git --git-dir=dst/.git config \
299 receive.fsck.missingEmail warn &&
300 git push --porcelain dst bogus >act 2>&1 &&
301 test_grep "missingEmail" act &&
302 test_grep "skipping unknown msg id.*whatever" act &&
303 git --git-dir=dst/.git branch -D bogus &&
304 git --git-dir=dst/.git config --add \
305 receive.fsck.missingEmail ignore &&
306 git push --porcelain dst bogus >act 2>&1 &&
307 test_grep ! "missingEmail" act
308 '
309
310 test_expect_success 'fetch with fetch.fsck.missingEmail=warn' '
311 refspec=refs/heads/bogus:refs/heads/bogus &&
312 git push . $commit:refs/heads/bogus &&
313 rm -rf dst &&
314 git init dst &&
315 git --git-dir=dst/.git config fetch.fsckobjects true &&
316 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
317
318 # fetch.fsck.<msg-id> does not fall back on fsck.<msg-id>
319 git --git-dir=dst/.git config fsck.missingEmail warn &&
320 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
321
322 # receive.fsck.<unknownmsg-id> warns
323 git --git-dir=dst/.git config \
324 fetch.fsck.whatEver error &&
325
326 git --git-dir=dst/.git config \
327 fetch.fsck.missingEmail warn &&
328 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
329 test_grep "missingEmail" act &&
330 test_grep "Skipping unknown msg id.*whatever" act &&
331 rm -rf dst &&
332 git init dst &&
333 git --git-dir=dst/.git config fetch.fsckobjects true &&
334 git --git-dir=dst/.git config \
335 fetch.fsck.missingEmail ignore &&
336 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
337 test_grep ! "missingEmail" act
338 '
339
340 test_expect_success \
341 'receive.fsck.unterminatedHeader=warn triggers error' '
342 rm -rf dst &&
343 git init dst &&
344 git --git-dir=dst/.git config receive.fsckobjects true &&
345 git --git-dir=dst/.git config \
346 receive.fsck.unterminatedheader warn &&
347 test_must_fail git push --porcelain dst HEAD >act 2>&1 &&
348 test_grep "Cannot demote unterminatedheader" act
349 '
350
351 test_expect_success \
352 'fetch.fsck.unterminatedHeader=warn triggers error' '
353 rm -rf dst &&
354 git init dst &&
355 git --git-dir=dst/.git config fetch.fsckobjects true &&
356 git --git-dir=dst/.git config \
357 fetch.fsck.unterminatedheader warn &&
358 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" HEAD &&
359 test_grep "Cannot demote unterminatedheader" act
360 '
361
362 test_expect_success PERL_TEST_HELPERS 'badFilemode is not a strict error' '
363 git init --bare badmode.git &&
364 tree=$(
365 cd badmode.git &&
366 blob=$(echo blob | git hash-object -w --stdin | hex2oct) &&
367 printf "123456 foo\0${blob}" |
368 git hash-object -t tree --stdin -w --literally
369 ) &&
370
371 rm -rf dst.git &&
372 git init --bare dst.git &&
373 git -C dst.git config transfer.fsckObjects true &&
374
375 git -C badmode.git push ../dst.git $tree:refs/tags/tree 2>err &&
376 test_grep "$tree: badFilemode" err
377 '
378
379 test_done