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