t4117: use modern test_* helpers
[git] / t / t0020-crlf.sh
1 #!/bin/sh
2
3 test_description='CRLF conversion'
4
5 . ./test-lib.sh
6
7 has_cr() {
8         tr '\015' Q <"$1" | grep Q >/dev/null
9 }
10
11 test_expect_success setup '
12
13         git config core.autocrlf false &&
14
15         for w in Hello world how are you; do echo $w; done >one &&
16         mkdir dir &&
17         for w in I am very very fine thank you; do echo $w; done >dir/two &&
18         for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&
19         git add . &&
20
21         git commit -m initial &&
22
23         one=$(git rev-parse HEAD:one) &&
24         dir=$(git rev-parse HEAD:dir) &&
25         two=$(git rev-parse HEAD:dir/two) &&
26         three=$(git rev-parse HEAD:three) &&
27
28         for w in Some extra lines here; do echo $w; done >>one &&
29         git diff >patch.file &&
30         patched=$(git hash-object --stdin <one) &&
31         git read-tree --reset -u HEAD &&
32
33         echo happy.
34 '
35
36 test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
37
38         git config core.autocrlf input &&
39         git config core.safecrlf true &&
40
41         for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
42         test_must_fail git add allcrlf
43 '
44
45 test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
46
47         git config core.autocrlf input &&
48         git config core.safecrlf true &&
49
50         for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
51         test_must_fail git add mixed
52 '
53
54 test_expect_success 'safecrlf: autocrlf=true, all LF' '
55
56         git config core.autocrlf true &&
57         git config core.safecrlf true &&
58
59         for w in I am all LF; do echo $w; done >alllf &&
60         test_must_fail git add alllf
61 '
62
63 test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
64
65         git config core.autocrlf true &&
66         git config core.safecrlf true &&
67
68         for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
69         test_must_fail git add mixed
70 '
71
72 test_expect_success 'safecrlf: print warning only once' '
73
74         git config core.autocrlf input &&
75         git config core.safecrlf warn &&
76
77         for w in I am all LF; do echo $w; done >doublewarn &&
78         git add doublewarn &&
79         git commit -m "nowarn" &&
80         for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
81         test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1
82 '
83
84
85 test_expect_success 'safecrlf: git diff demotes safecrlf=true to warn' '
86         git config core.autocrlf input &&
87         git config core.safecrlf true &&
88         git diff HEAD
89 '
90
91
92 test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
93         git config core.autocrlf false &&
94         git config core.safecrlf false &&
95         git reset --hard HEAD^
96 '
97
98 test_expect_success 'update with autocrlf=input' '
99
100         rm -f tmp one dir/two three &&
101         git read-tree --reset -u HEAD &&
102         git config core.autocrlf input &&
103
104         for f in one dir/two
105         do
106                 append_cr <$f >tmp && mv -f tmp $f &&
107                 git update-index -- $f ||
108                 break
109         done &&
110
111         differs=$(git diff-index --cached HEAD) &&
112         verbose test -z "$differs"
113
114 '
115
116 test_expect_success 'update with autocrlf=true' '
117
118         rm -f tmp one dir/two three &&
119         git read-tree --reset -u HEAD &&
120         git config core.autocrlf true &&
121
122         for f in one dir/two
123         do
124                 append_cr <$f >tmp && mv -f tmp $f &&
125                 git update-index -- $f ||
126                 break
127         done &&
128
129         differs=$(git diff-index --cached HEAD) &&
130         verbose test -z "$differs"
131
132 '
133
134 test_expect_success 'checkout with autocrlf=true' '
135
136         rm -f tmp one dir/two three &&
137         git config core.autocrlf true &&
138         git read-tree --reset -u HEAD &&
139
140         for f in one dir/two
141         do
142                 remove_cr <"$f" >tmp && mv -f tmp $f &&
143                 verbose git update-index -- $f ||
144                 break
145         done &&
146         test "$one" = $(git hash-object --stdin <one) &&
147         test "$two" = $(git hash-object --stdin <dir/two) &&
148         differs=$(git diff-index --cached HEAD) &&
149         verbose test -z "$differs"
150 '
151
152 test_expect_success 'checkout with autocrlf=input' '
153
154         rm -f tmp one dir/two three &&
155         git config core.autocrlf input &&
156         git read-tree --reset -u HEAD &&
157
158         for f in one dir/two
159         do
160                 if has_cr "$f"
161                 then
162                         echo "Eh? $f"
163                         false
164                         break
165                 else
166                         git update-index -- $f
167                 fi
168         done &&
169         test "$one" = $(git hash-object --stdin <one) &&
170         test "$two" = $(git hash-object --stdin <dir/two) &&
171         differs=$(git diff-index --cached HEAD) &&
172         verbose test -z "$differs"
173 '
174
175 test_expect_success 'apply patch (autocrlf=input)' '
176
177         rm -f tmp one dir/two three &&
178         git config core.autocrlf input &&
179         git read-tree --reset -u HEAD &&
180
181         git apply patch.file &&
182         verbose test "$patched" = "$(git hash-object --stdin <one)"
183 '
184
185 test_expect_success 'apply patch --cached (autocrlf=input)' '
186
187         rm -f tmp one dir/two three &&
188         git config core.autocrlf input &&
189         git read-tree --reset -u HEAD &&
190
191         git apply --cached patch.file &&
192         verbose test "$patched" = $(git rev-parse :one)
193 '
194
195 test_expect_success 'apply patch --index (autocrlf=input)' '
196
197         rm -f tmp one dir/two three &&
198         git config core.autocrlf input &&
199         git read-tree --reset -u HEAD &&
200
201         git apply --index patch.file &&
202         verbose test "$patched" = $(git rev-parse :one) &&
203         verbose test "$patched" = $(git hash-object --stdin <one)
204 '
205
206 test_expect_success 'apply patch (autocrlf=true)' '
207
208         rm -f tmp one dir/two three &&
209         git config core.autocrlf true &&
210         git read-tree --reset -u HEAD &&
211
212         git apply patch.file &&
213         verbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"
214 '
215
216 test_expect_success 'apply patch --cached (autocrlf=true)' '
217
218         rm -f tmp one dir/two three &&
219         git config core.autocrlf true &&
220         git read-tree --reset -u HEAD &&
221
222         git apply --cached patch.file &&
223         verbose test "$patched" = $(git rev-parse :one)
224 '
225
226 test_expect_success 'apply patch --index (autocrlf=true)' '
227
228         rm -f tmp one dir/two three &&
229         git config core.autocrlf true &&
230         git read-tree --reset -u HEAD &&
231
232         git apply --index patch.file &&
233         verbose test "$patched" = $(git rev-parse :one) &&
234         verbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"
235 '
236
237 test_expect_success '.gitattributes says two is binary' '
238
239         rm -f tmp one dir/two three &&
240         echo "two -crlf" >.gitattributes &&
241         git config core.autocrlf true &&
242         git read-tree --reset -u HEAD &&
243
244         if has_cr dir/two
245         then
246                 echo "Huh?"
247                 false
248         else
249                 : happy
250         fi &&
251
252         if has_cr one
253         then
254                 : happy
255         else
256                 echo "Huh?"
257                 false
258         fi &&
259
260         if has_cr three
261         then
262                 echo "Huh?"
263                 false
264         else
265                 : happy
266         fi
267 '
268
269 test_expect_success '.gitattributes says two is input' '
270
271         rm -f tmp one dir/two three &&
272         echo "two crlf=input" >.gitattributes &&
273         git read-tree --reset -u HEAD &&
274
275         if has_cr dir/two
276         then
277                 echo "Huh?"
278                 false
279         else
280                 : happy
281         fi
282 '
283
284 test_expect_success '.gitattributes says two and three are text' '
285
286         rm -f tmp one dir/two three &&
287         echo "t* crlf" >.gitattributes &&
288         git read-tree --reset -u HEAD &&
289
290         verbose has_cr dir/two &&
291         verbose has_cr three
292 '
293
294 test_expect_success 'in-tree .gitattributes (1)' '
295
296         echo "one -crlf" >>.gitattributes &&
297         git add .gitattributes &&
298         git commit -m "Add .gitattributes" &&
299
300         rm -rf tmp one dir .gitattributes patch.file three &&
301         git read-tree --reset -u HEAD &&
302
303         test_must_fail has_cr one &&
304         verbose has_cr three
305 '
306
307 test_expect_success 'in-tree .gitattributes (2)' '
308
309         rm -rf tmp one dir .gitattributes patch.file three &&
310         git read-tree --reset HEAD &&
311         git checkout-index -f -q -u -a &&
312
313         test_must_fail has_cr one &&
314         verbose has_cr three
315 '
316
317 test_expect_success 'in-tree .gitattributes (3)' '
318
319         rm -rf tmp one dir .gitattributes patch.file three &&
320         git read-tree --reset HEAD &&
321         git checkout-index -u .gitattributes &&
322         git checkout-index -u one dir/two three &&
323
324         test_must_fail has_cr one &&
325         verbose has_cr three
326 '
327
328 test_expect_success 'in-tree .gitattributes (4)' '
329
330         rm -rf tmp one dir .gitattributes patch.file three &&
331         git read-tree --reset HEAD &&
332         git checkout-index -u one dir/two three &&
333         git checkout-index -u .gitattributes &&
334
335         test_must_fail has_cr one &&
336         verbose has_cr three
337 '
338
339 test_expect_success 'checkout with existing .gitattributes' '
340
341         git config core.autocrlf true &&
342         git config --unset core.safecrlf &&
343         echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
344         git add .gitattributes &&
345         git commit -m initial &&
346         echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
347         echo "contents" > .file &&
348         git add .gitattributes .file &&
349         git commit -m second &&
350
351         git checkout master~1 &&
352         git checkout master &&
353         test "$(git diff-files --raw)" = ""
354
355 '
356
357 test_expect_success 'checkout when deleting .gitattributes' '
358
359         git rm .gitattributes &&
360         echo "contentsQ" | q_to_cr > .file2 &&
361         git add .file2 &&
362         git commit -m third &&
363
364         git checkout master~1 &&
365         git checkout master &&
366         has_cr .file2
367
368 '
369
370 test_expect_success 'invalid .gitattributes (must not crash)' '
371
372         echo "three +crlf" >>.gitattributes &&
373         git diff
374
375 '
376 # Some more tests here to add new autocrlf functionality.
377 # We want to have a known state here, so start a bit from scratch
378
379 test_expect_success 'setting up for new autocrlf tests' '
380         git config core.autocrlf false &&
381         git config core.safecrlf false &&
382         rm -rf .????* * &&
383         for w in I am all LF; do echo $w; done >alllf &&
384         for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
385         for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
386         git add -A . &&
387         git commit -m "alllf, allcrlf and mixed only" &&
388         git tag -a -m "message" autocrlf-checkpoint
389 '
390
391 test_expect_success 'report no change after setting autocrlf' '
392         git config core.autocrlf true &&
393         touch * &&
394         git diff --exit-code
395 '
396
397 test_expect_success 'files are clean after checkout' '
398         rm * &&
399         git checkout -f &&
400         git diff --exit-code
401 '
402
403 cr_to_Q_no_NL () {
404     tr '\015' Q | tr -d '\012'
405 }
406
407 test_expect_success 'LF only file gets CRLF with autocrlf' '
408         test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
409 '
410
411 test_expect_success 'Mixed file is still mixed with autocrlf' '
412         test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
413 '
414
415 test_expect_success 'CRLF only file has CRLF with autocrlf' '
416         test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
417 '
418
419 test_expect_success 'New CRLF file gets LF in repo' '
420         tr -d "\015" < alllf | append_cr > alllf2 &&
421         git add alllf2 &&
422         git commit -m "alllf2 added" &&
423         git config core.autocrlf false &&
424         rm * &&
425         git checkout -f &&
426         test_cmp alllf alllf2
427 '
428
429 test_done