Merge git://repo.or.cz/git-gui
[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                         echo Oops
109                         false
110                         break
111                 }
112         done &&
113
114         differs=$(git diff-index --cached HEAD) &&
115         test -z "$differs" || {
116                 echo Oops "$differs"
117                 false
118         }
119
120 '
121
122 test_expect_success 'update with autocrlf=true' '
123
124         rm -f tmp one dir/two three &&
125         git read-tree --reset -u HEAD &&
126         git config core.autocrlf true &&
127
128         for f in one dir/two
129         do
130                 append_cr <$f >tmp && mv -f tmp $f &&
131                 git update-index -- $f || {
132                         echo "Oops $f"
133                         false
134                         break
135                 }
136         done &&
137
138         differs=$(git diff-index --cached HEAD) &&
139         test -z "$differs" || {
140                 echo Oops "$differs"
141                 false
142         }
143
144 '
145
146 test_expect_success 'checkout with autocrlf=true' '
147
148         rm -f tmp one dir/two three &&
149         git config core.autocrlf true &&
150         git read-tree --reset -u HEAD &&
151
152         for f in one dir/two
153         do
154                 remove_cr <"$f" >tmp && mv -f tmp $f &&
155                 git update-index -- $f || {
156                         echo "Eh? $f"
157                         false
158                         break
159                 }
160         done &&
161         test "$one" = $(git hash-object --stdin <one) &&
162         test "$two" = $(git hash-object --stdin <dir/two) &&
163         differs=$(git diff-index --cached HEAD) &&
164         test -z "$differs" || {
165                 echo Oops "$differs"
166                 false
167         }
168 '
169
170 test_expect_success 'checkout with autocrlf=input' '
171
172         rm -f tmp one dir/two three &&
173         git config core.autocrlf input &&
174         git read-tree --reset -u HEAD &&
175
176         for f in one dir/two
177         do
178                 if has_cr "$f"
179                 then
180                         echo "Eh? $f"
181                         false
182                         break
183                 else
184                         git update-index -- $f
185                 fi
186         done &&
187         test "$one" = $(git hash-object --stdin <one) &&
188         test "$two" = $(git hash-object --stdin <dir/two) &&
189         differs=$(git diff-index --cached HEAD) &&
190         test -z "$differs" || {
191                 echo Oops "$differs"
192                 false
193         }
194 '
195
196 test_expect_success 'apply patch (autocrlf=input)' '
197
198         rm -f tmp one dir/two three &&
199         git config core.autocrlf input &&
200         git read-tree --reset -u HEAD &&
201
202         git apply patch.file &&
203         test "$patched" = "$(git hash-object --stdin <one)" || {
204                 echo "Eh?  apply without index"
205                 false
206         }
207 '
208
209 test_expect_success 'apply patch --cached (autocrlf=input)' '
210
211         rm -f tmp one dir/two three &&
212         git config core.autocrlf input &&
213         git read-tree --reset -u HEAD &&
214
215         git apply --cached patch.file &&
216         test "$patched" = $(git rev-parse :one) || {
217                 echo "Eh?  apply with --cached"
218                 false
219         }
220 '
221
222 test_expect_success 'apply patch --index (autocrlf=input)' '
223
224         rm -f tmp one dir/two three &&
225         git config core.autocrlf input &&
226         git read-tree --reset -u HEAD &&
227
228         git apply --index patch.file &&
229         test "$patched" = $(git rev-parse :one) &&
230         test "$patched" = $(git hash-object --stdin <one) || {
231                 echo "Eh?  apply with --index"
232                 false
233         }
234 '
235
236 test_expect_success 'apply patch (autocrlf=true)' '
237
238         rm -f tmp one dir/two three &&
239         git config core.autocrlf true &&
240         git read-tree --reset -u HEAD &&
241
242         git apply patch.file &&
243         test "$patched" = "$(remove_cr <one | git hash-object --stdin)" || {
244                 echo "Eh?  apply without index"
245                 false
246         }
247 '
248
249 test_expect_success 'apply patch --cached (autocrlf=true)' '
250
251         rm -f tmp one dir/two three &&
252         git config core.autocrlf true &&
253         git read-tree --reset -u HEAD &&
254
255         git apply --cached patch.file &&
256         test "$patched" = $(git rev-parse :one) || {
257                 echo "Eh?  apply without index"
258                 false
259         }
260 '
261
262 test_expect_success 'apply patch --index (autocrlf=true)' '
263
264         rm -f tmp one dir/two three &&
265         git config core.autocrlf true &&
266         git read-tree --reset -u HEAD &&
267
268         git apply --index patch.file &&
269         test "$patched" = $(git rev-parse :one) &&
270         test "$patched" = "$(remove_cr <one | git hash-object --stdin)" || {
271                 echo "Eh?  apply with --index"
272                 false
273         }
274 '
275
276 test_expect_success '.gitattributes says two is binary' '
277
278         rm -f tmp one dir/two three &&
279         echo "two -crlf" >.gitattributes &&
280         git config core.autocrlf true &&
281         git read-tree --reset -u HEAD &&
282
283         if has_cr dir/two
284         then
285                 echo "Huh?"
286                 false
287         else
288                 : happy
289         fi &&
290
291         if has_cr one
292         then
293                 : happy
294         else
295                 echo "Huh?"
296                 false
297         fi &&
298
299         if has_cr three
300         then
301                 echo "Huh?"
302                 false
303         else
304                 : happy
305         fi
306 '
307
308 test_expect_success '.gitattributes says two is input' '
309
310         rm -f tmp one dir/two three &&
311         echo "two crlf=input" >.gitattributes &&
312         git read-tree --reset -u HEAD &&
313
314         if has_cr dir/two
315         then
316                 echo "Huh?"
317                 false
318         else
319                 : happy
320         fi
321 '
322
323 test_expect_success '.gitattributes says two and three are text' '
324
325         rm -f tmp one dir/two three &&
326         echo "t* crlf" >.gitattributes &&
327         git read-tree --reset -u HEAD &&
328
329         if has_cr dir/two
330         then
331                 : happy
332         else
333                 echo "Huh?"
334                 false
335         fi &&
336
337         if has_cr three
338         then
339                 : happy
340         else
341                 echo "Huh?"
342                 false
343         fi
344 '
345
346 test_expect_success 'in-tree .gitattributes (1)' '
347
348         echo "one -crlf" >>.gitattributes &&
349         git add .gitattributes &&
350         git commit -m "Add .gitattributes" &&
351
352         rm -rf tmp one dir .gitattributes patch.file three &&
353         git read-tree --reset -u HEAD &&
354
355         if has_cr one
356         then
357                 echo "Eh? one should not have CRLF"
358                 false
359         else
360                 : happy
361         fi &&
362         has_cr three || {
363                 echo "Eh? three should still have CRLF"
364                 false
365         }
366 '
367
368 test_expect_success 'in-tree .gitattributes (2)' '
369
370         rm -rf tmp one dir .gitattributes patch.file three &&
371         git read-tree --reset HEAD &&
372         git checkout-index -f -q -u -a &&
373
374         if has_cr one
375         then
376                 echo "Eh? one should not have CRLF"
377                 false
378         else
379                 : happy
380         fi &&
381         has_cr three || {
382                 echo "Eh? three should still have CRLF"
383                 false
384         }
385 '
386
387 test_expect_success 'in-tree .gitattributes (3)' '
388
389         rm -rf tmp one dir .gitattributes patch.file three &&
390         git read-tree --reset HEAD &&
391         git checkout-index -u .gitattributes &&
392         git checkout-index -u one dir/two three &&
393
394         if has_cr one
395         then
396                 echo "Eh? one should not have CRLF"
397                 false
398         else
399                 : happy
400         fi &&
401         has_cr three || {
402                 echo "Eh? three should still have CRLF"
403                 false
404         }
405 '
406
407 test_expect_success 'in-tree .gitattributes (4)' '
408
409         rm -rf tmp one dir .gitattributes patch.file three &&
410         git read-tree --reset HEAD &&
411         git checkout-index -u one dir/two three &&
412         git checkout-index -u .gitattributes &&
413
414         if has_cr one
415         then
416                 echo "Eh? one should not have CRLF"
417                 false
418         else
419                 : happy
420         fi &&
421         has_cr three || {
422                 echo "Eh? three should still have CRLF"
423                 false
424         }
425 '
426
427 test_expect_success 'checkout with existing .gitattributes' '
428
429         git config core.autocrlf true &&
430         git config --unset core.safecrlf &&
431         echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
432         git add .gitattributes &&
433         git commit -m initial &&
434         echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
435         echo "contents" > .file &&
436         git add .gitattributes .file &&
437         git commit -m second &&
438
439         git checkout master~1 &&
440         git checkout master &&
441         test "$(git diff-files --raw)" = ""
442
443 '
444
445 test_expect_success 'checkout when deleting .gitattributes' '
446
447         git rm .gitattributes &&
448         echo "contentsQ" | q_to_cr > .file2 &&
449         git add .file2 &&
450         git commit -m third &&
451
452         git checkout master~1 &&
453         git checkout master &&
454         has_cr .file2
455
456 '
457
458 test_expect_success 'invalid .gitattributes (must not crash)' '
459
460         echo "three +crlf" >>.gitattributes &&
461         git diff
462
463 '
464 # Some more tests here to add new autocrlf functionality.
465 # We want to have a known state here, so start a bit from scratch
466
467 test_expect_success 'setting up for new autocrlf tests' '
468         git config core.autocrlf false &&
469         git config core.safecrlf false &&
470         rm -rf .????* * &&
471         for w in I am all LF; do echo $w; done >alllf &&
472         for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
473         for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
474         git add -A . &&
475         git commit -m "alllf, allcrlf and mixed only" &&
476         git tag -a -m "message" autocrlf-checkpoint
477 '
478
479 test_expect_success 'report no change after setting autocrlf' '
480         git config core.autocrlf true &&
481         touch * &&
482         git diff --exit-code
483 '
484
485 test_expect_success 'files are clean after checkout' '
486         rm * &&
487         git checkout -f &&
488         git diff --exit-code
489 '
490
491 cr_to_Q_no_NL () {
492     tr '\015' Q | tr -d '\012'
493 }
494
495 test_expect_success 'LF only file gets CRLF with autocrlf' '
496         test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
497 '
498
499 test_expect_success 'Mixed file is still mixed with autocrlf' '
500         test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
501 '
502
503 test_expect_success 'CRLF only file has CRLF with autocrlf' '
504         test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
505 '
506
507 test_expect_success 'New CRLF file gets LF in repo' '
508         tr -d "\015" < alllf | append_cr > alllf2 &&
509         git add alllf2 &&
510         git commit -m "alllf2 added" &&
511         git config core.autocrlf false &&
512         rm * &&
513         git checkout -f &&
514         test_cmp alllf alllf2
515 '
516
517 test_done