3 test_description
='fetch/receive strict mode'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7 TEST_PASSES_SANITIZE_LEAK
=true
10 test_expect_success
'setup and inject "corrupt or missing" object' '
11 echo hello >greetings &&
13 git commit -m greetings &&
15 S=$(git rev-parse :greetings | sed -e "s|^..|&/|") &&
16 X=$(echo bye | git hash-object -w --stdin | sed -e "s|^..|&/|") &&
19 cp .git/objects/$S .git/objects/$S.back &&
20 mv -f .git/objects/$X .git/objects/$S &&
22 test_must_fail git fsck
25 test_expect_success
'fetch without strict' '
30 git config fetch.fsckobjects false &&
31 git config transfer.fsckobjects false &&
32 test_must_fail git fetch ../.git main
36 test_expect_success
'fetch with !fetch.fsckobjects' '
41 git config fetch.fsckobjects false &&
42 git config transfer.fsckobjects true &&
43 test_must_fail git fetch ../.git main
47 test_expect_success
'fetch with fetch.fsckobjects' '
52 git config fetch.fsckobjects true &&
53 git config transfer.fsckobjects false &&
54 test_must_fail git fetch ../.git main
58 test_expect_success
'fetch with transfer.fsckobjects' '
63 git config transfer.fsckobjects true &&
64 test_must_fail git fetch ../.git main
70 ! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects)
74 test_expect_success
'push without strict' '
79 git config fetch.fsckobjects false &&
80 git config transfer.fsckobjects false
82 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
86 test_expect_success
'push with !receive.fsckobjects' '
91 git config receive.fsckobjects false &&
92 git config transfer.fsckobjects true
94 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
100 ! refs/heads/main:refs/heads/test [remote rejected] (unpacker error)
103 test_expect_success
'push with receive.fsckobjects' '
108 git config receive.fsckobjects true &&
109 git config transfer.fsckobjects false
111 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
115 test_expect_success
'push with transfer.fsckobjects' '
120 git config transfer.fsckobjects true
122 test_must_fail git push --porcelain dst main:refs/heads/test >act &&
126 test_expect_success
'repair the "corrupt or missing" object' '
127 mv -f .git/objects/$(cat S) .git/objects/$(cat X) &&
128 mv .git/objects/$(cat S).back .git/objects/$(cat S) &&
129 rm -rf .git/objects/$(cat X) &&
133 cat >bogus-commit
<<EOF
135 author Bugs Bunny 1234567890 +0000
136 committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000
138 This commit object intentionally broken
141 test_expect_success
'setup bogus commit' '
142 commit="$(git hash-object --literally -t commit -w --stdin <bogus-commit)"
145 test_expect_success
'fsck with no skipList input' '
146 test_must_fail git fsck 2>err &&
147 test_grep "missingEmail" err
150 test_expect_success
'setup sorted and unsorted skipLists' '
151 cat >SKIP.unsorted <<-EOF &&
158 sort SKIP.unsorted >SKIP.sorted
161 test_expect_success
'fsck with sorted skipList' '
162 git -c fsck.skipList=SKIP.sorted fsck
165 test_expect_success
'fsck with unsorted skipList' '
166 git -c fsck.skipList=SKIP.unsorted fsck
169 test_expect_success
'fsck with invalid or bogus skipList input' '
170 git -c fsck.skipList=/dev/null -c fsck.missingEmail=ignore fsck &&
171 test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err &&
172 test_grep "could not open.*: does-not-exist" err &&
173 test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err &&
174 test_grep "invalid object name: \[core\]" err
177 test_expect_success
'fsck with other accepted skipList input (comments & empty lines)' '
178 cat >SKIP.with-comment <<-EOF &&
182 test_must_fail git -c fsck.skipList=SKIP.with-comment fsck 2>err-with-comment &&
183 test_grep "missingEmail" err-with-comment &&
184 cat >SKIP.with-empty-line <<-EOF &&
189 test_must_fail git -c fsck.skipList=SKIP.with-empty-line fsck 2>err-with-empty-line &&
190 test_grep "missingEmail" err-with-empty-line
193 test_expect_success
'fsck no garbage output from comments & empty lines errors' '
194 test_line_count = 1 err-with-comment &&
195 test_line_count = 1 err-with-empty-line
198 test_expect_success
'fsck with invalid abbreviated skipList input' '
199 echo $commit | test_copy_bytes 20 >SKIP.abbreviated &&
200 test_must_fail git -c fsck.skipList=SKIP.abbreviated fsck 2>err-abbreviated &&
201 test_grep "^fatal: invalid object name: " err-abbreviated
204 test_expect_success
'fsck with exhaustive accepted skipList input (various types of comments etc.)' '
206 echo "# A commented line" >>SKIP.exhaustive &&
207 echo "" >>SKIP.exhaustive &&
208 echo " " >>SKIP.exhaustive &&
209 echo " # Comment after whitespace" >>SKIP.exhaustive &&
210 echo "$commit # Our bad commit (with leading whitespace and trailing comment)" >>SKIP.exhaustive &&
211 echo "# Some bad commit (leading whitespace)" >>SKIP.exhaustive &&
212 echo " $(test_oid 001)" >>SKIP.exhaustive &&
213 git -c fsck.skipList=SKIP.exhaustive fsck 2>err &&
214 test_must_be_empty err
217 test_expect_success
'push with receive.fsck.skipList' '
218 git push . $commit:refs/heads/bogus &&
221 git --git-dir=dst/.git config receive.fsckObjects true &&
222 test_must_fail git push --porcelain dst bogus &&
223 echo $commit >dst/.git/SKIP &&
225 # receive.fsck.* does not fall back on fsck.*
226 git --git-dir=dst/.git config fsck.skipList SKIP &&
227 test_must_fail git push --porcelain dst bogus &&
229 # Invalid and/or bogus skipList input
230 git --git-dir=dst/.git config receive.fsck.skipList /dev/null &&
231 test_must_fail git push --porcelain dst bogus &&
232 git --git-dir=dst/.git config receive.fsck.skipList does-not-exist &&
233 test_must_fail git push --porcelain dst bogus 2>err &&
234 test_grep "could not open.*: does-not-exist" err &&
235 git --git-dir=dst/.git config receive.fsck.skipList config &&
236 test_must_fail git push --porcelain dst bogus 2>err &&
237 test_grep "invalid object name: \[core\]" err &&
239 git --git-dir=dst/.git config receive.fsck.skipList SKIP &&
240 git push --porcelain dst bogus
243 test_expect_success
'fetch with fetch.fsck.skipList' '
244 refspec=refs/heads/bogus:refs/heads/bogus &&
245 git push . $commit:refs/heads/bogus &&
248 git --git-dir=dst/.git config fetch.fsckObjects true &&
249 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
250 git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
251 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
252 echo $commit >dst/.git/SKIP &&
254 # fetch.fsck.* does not fall back on fsck.*
255 git --git-dir=dst/.git config fsck.skipList dst/.git/SKIP &&
256 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
258 # Invalid and/or bogus skipList input
259 git --git-dir=dst/.git config fetch.fsck.skipList /dev/null &&
260 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
261 git --git-dir=dst/.git config fetch.fsck.skipList does-not-exist &&
262 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
263 test_grep "could not open.*: does-not-exist" err &&
264 git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config &&
265 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err &&
266 test_grep "invalid object name: \[core\]" err &&
268 git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP &&
269 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec
272 test_expect_success
'fsck.<unknownmsg-id> dies' '
273 test_must_fail git -c fsck.whatEver=ignore fsck 2>err &&
274 test_grep "Unhandled message id: whatever" err
277 test_expect_success
'push with receive.fsck.missingEmail=warn' '
278 git push . $commit:refs/heads/bogus &&
281 git --git-dir=dst/.git config receive.fsckobjects true &&
282 test_must_fail git push --porcelain dst bogus &&
284 # receive.fsck.<msg-id> does not fall back on fsck.<msg-id>
285 git --git-dir=dst/.git config fsck.missingEmail warn &&
286 test_must_fail git push --porcelain dst bogus &&
288 # receive.fsck.<unknownmsg-id> warns
289 git --git-dir=dst/.git config \
290 receive.fsck.whatEver error &&
292 git --git-dir=dst/.git config \
293 receive.fsck.missingEmail warn &&
294 git push --porcelain dst bogus >act 2>&1 &&
295 grep "missingEmail" act &&
296 test_grep "skipping unknown msg id.*whatever" act &&
297 git --git-dir=dst/.git branch -D bogus &&
298 git --git-dir=dst/.git config --add \
299 receive.fsck.missingEmail ignore &&
300 git push --porcelain dst bogus >act 2>&1 &&
301 ! grep "missingEmail" act
304 test_expect_success
'fetch with fetch.fsck.missingEmail=warn' '
305 refspec=refs/heads/bogus:refs/heads/bogus &&
306 git push . $commit:refs/heads/bogus &&
309 git --git-dir=dst/.git config fetch.fsckobjects true &&
310 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
312 # fetch.fsck.<msg-id> does not fall back on fsck.<msg-id>
313 git --git-dir=dst/.git config fsck.missingEmail warn &&
314 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec &&
316 # receive.fsck.<unknownmsg-id> warns
317 git --git-dir=dst/.git config \
318 fetch.fsck.whatEver error &&
320 git --git-dir=dst/.git config \
321 fetch.fsck.missingEmail warn &&
322 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
323 grep "missingEmail" act &&
324 test_grep "Skipping unknown msg id.*whatever" act &&
327 git --git-dir=dst/.git config fetch.fsckobjects true &&
328 git --git-dir=dst/.git config \
329 fetch.fsck.missingEmail ignore &&
330 git --git-dir=dst/.git fetch "file://$(pwd)" $refspec >act 2>&1 &&
331 ! grep "missingEmail" act
334 test_expect_success \
335 'receive.fsck.unterminatedHeader=warn triggers error' '
338 git --git-dir=dst/.git config receive.fsckobjects true &&
339 git --git-dir=dst/.git config \
340 receive.fsck.unterminatedheader warn &&
341 test_must_fail git push --porcelain dst HEAD >act 2>&1 &&
342 grep "Cannot demote unterminatedheader" act
345 test_expect_success \
346 'fetch.fsck.unterminatedHeader=warn triggers error' '
349 git --git-dir=dst/.git config fetch.fsckobjects true &&
350 git --git-dir=dst/.git config \
351 fetch.fsck.unterminatedheader warn &&
352 test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" HEAD &&
353 grep "Cannot demote unterminatedheader" act
356 test_expect_success
'badFilemode is not a strict error' '
357 git init --bare badmode.git &&
360 blob=$(echo blob | git hash-object -w --stdin | hex2oct) &&
361 printf "123456 foo\0${blob}" |
362 git hash-object -t tree --stdin -w --literally
366 git init --bare dst.git &&
367 git -C dst.git config transfer.fsckObjects true &&
369 git -C badmode.git push ../dst.git $tree:refs/tags/tree 2>err &&
370 grep "$tree: badFilemode" err