The second batch
[git] / t / t0027-auto-crlf.sh
1 #!/bin/sh
2
3 test_description='CRLF conversion all combinations'
4
5 . ./test-lib.sh
6
7 compare_files () {
8         tr '\015\000' QN <"$1" >"$1".expect &&
9         tr '\015\000' QN <"$2" | tr -d 'Z' >"$2".actual &&
10         test_cmp "$1".expect "$2".actual &&
11         rm "$1".expect "$2".actual
12 }
13
14 compare_ws_file () {
15         pfx=$1
16         exp=$2.expect
17         act=$pfx.actual.$3
18         tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" |
19                 sed -e "s/0000*/$ZERO_OID/" >"$exp" &&
20         tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" |
21                 sed -e "s/0000*/$ZERO_OID/" >"$act" &&
22         test_cmp "$exp" "$act" &&
23         rm "$exp" "$act"
24 }
25
26 create_gitattributes () {
27         {
28                 while test "$#" != 0
29                 do
30                         case "$1" in
31                         auto)    echo '*.txt text=auto' ;;
32                         ident) echo '*.txt ident' ;;
33                         text)    echo '*.txt text' ;;
34                         -text) echo '*.txt -text' ;;
35                         crlf)  echo '*.txt eol=crlf' ;;
36                         lf)    echo '*.txt eol=lf' ;;
37                         "") ;;
38                         *)
39                                 echo >&2 invalid attribute: "$1"
40                                 exit 1
41                                 ;;
42                         esac &&
43                         shift
44                 done
45         } >.gitattributes
46 }
47
48 # Create 2 sets of files:
49 # The NNO files are "Not NOrmalized in the repo. We use CRLF_mix_LF and store
50 #   it under different names for the different test cases, see ${pfx}
51 #   Depending on .gitattributes they are normalized at the next commit (or not)
52 # The MIX files have different contents in the repo.
53 #   Depending on its contents, the "new safer autocrlf" may kick in.
54 create_NNO_MIX_files () {
55         for crlf in false true input
56         do
57                 for attr in "" auto text -text
58                 do
59                         for aeol in "" lf crlf
60                         do
61                                 pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} &&
62                                 cp CRLF_mix_LF ${pfx}_LF.txt &&
63                                 cp CRLF_mix_LF ${pfx}_CRLF.txt &&
64                                 cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
65                                 cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt &&
66                                 cp CRLF_mix_LF ${pfx}_CRLF_nul.txt &&
67                                 pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf} &&
68                                 cp LF          ${pfx}_LF.txt &&
69                                 cp CRLF        ${pfx}_CRLF.txt &&
70                                 cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
71                                 cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
72                                 cp CRLF_nul    ${pfx}_CRLF_nul.txt
73                         done
74                 done
75         done
76 }
77
78 check_warning () {
79         case "$1" in
80         LF_CRLF) echo "warning: LF will be replaced by CRLF" >"$2".expect ;;
81         CRLF_LF) echo "warning: CRLF will be replaced by LF" >"$2".expect ;;
82         '')                                                      >"$2".expect ;;
83         *) echo >&2 "Illegal 1": "$1" ; return false ;;
84         esac
85         grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq  >"$2".actual
86         test_cmp "$2".expect "$2".actual
87 }
88
89 commit_check_warn () {
90         crlf=$1
91         attr=$2
92         lfname=$3
93         crlfname=$4
94         lfmixcrlf=$5
95         lfmixcr=$6
96         crlfnul=$7
97         pfx=crlf_${crlf}_attr_${attr}
98         create_gitattributes "$attr" &&
99         for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul CRLF_nul
100         do
101                 fname=${pfx}_$f.txt &&
102                 cp $f $fname &&
103                 git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
104         done &&
105         git commit -m "core.autocrlf $crlf" &&
106         check_warning "$lfname" ${pfx}_LF.err &&
107         check_warning "$crlfname" ${pfx}_CRLF.err &&
108         check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err &&
109         check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err &&
110         check_warning "$crlfnul" ${pfx}_CRLF_nul.err
111 }
112
113 commit_chk_wrnNNO () {
114         attr=$1 ; shift
115         aeol=$1 ; shift
116         crlf=$1 ; shift
117         lfwarn=$1 ; shift
118         crlfwarn=$1 ; shift
119         lfmixcrlf=$1 ; shift
120         lfmixcr=$1 ; shift
121         crlfnul=$1 ; shift
122         pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
123         #Commit files on top of existing file
124         create_gitattributes "$attr" $aeol &&
125         for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
126         do
127                 fname=${pfx}_$f.txt &&
128                 cp $f $fname &&
129                 printf Z >>"$fname" &&
130                 git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
131         done
132
133         test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
134                 check_warning "$lfwarn" ${pfx}_LF.err
135         '
136         test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF" '
137                 check_warning "$crlfwarn" ${pfx}_CRLF.err
138         '
139
140         test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_mix_LF" '
141                 check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
142         '
143
144         test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf LF_mix_cr" '
145                 check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
146         '
147
148         test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_nul" '
149                 check_warning "$crlfnul" ${pfx}_CRLF_nul.err
150         '
151 }
152
153 # Commit a file with mixed line endings on top of different files
154 # in the index. Check for warnings
155 commit_MIX_chkwrn () {
156         attr=$1 ; shift
157         aeol=$1 ; shift
158         crlf=$1 ; shift
159         lfwarn=$1 ; shift
160         crlfwarn=$1 ; shift
161         lfmixcrlf=$1 ; shift
162         lfmixcr=$1 ; shift
163         crlfnul=$1 ; shift
164         pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
165         #Commit file with CLRF_mix_LF on top of existing file
166         create_gitattributes "$attr" $aeol &&
167         for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
168         do
169                 fname=${pfx}_$f.txt &&
170                 cp CRLF_mix_LF $fname &&
171                 printf Z >>"$fname" &&
172                 git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
173         done
174
175         test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
176                 check_warning "$lfwarn" ${pfx}_LF.err
177         '
178         test_expect_success "commit file with mixed EOL onto CLRF attr=$attr aeol=$aeol crlf=$crlf" '
179                 check_warning "$crlfwarn" ${pfx}_CRLF.err
180         '
181
182         test_expect_success "commit file with mixed EOL onto CRLF_mix_LF attr=$attr aeol=$aeol crlf=$crlf" '
183                 check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
184         '
185
186         test_expect_success "commit file with mixed EOL onto LF_mix_cr attr=$attr aeol=$aeol crlf=$crlf " '
187                 check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
188         '
189
190         test_expect_success "commit file with mixed EOL onto CRLF_nul attr=$attr aeol=$aeol crlf=$crlf" '
191                 check_warning "$crlfnul" ${pfx}_CRLF_nul.err
192         '
193 }
194
195
196 stats_ascii () {
197         case "$1" in
198         LF)
199                 echo lf
200                 ;;
201         CRLF)
202                 echo crlf
203                 ;;
204         CRLF_mix_LF)
205                 echo mixed
206                 ;;
207         LF_mix_CR|CRLF_nul|LF_nul|CRLF_mix_CR)
208                 echo "-text"
209                 ;;
210         *)
211                 echo error_invalid $1
212                 ;;
213         esac
214
215 }
216
217
218 # construct the attr/ returned by git ls-files --eol
219 # Take none (=empty), one or two args
220 # convert.c: eol=XX overrides text=auto
221 attr_ascii () {
222         case $1,$2 in
223         -text,*)   echo "-text" ;;
224         text,)     echo "text" ;;
225         text,lf)   echo "text eol=lf" ;;
226         text,crlf) echo "text eol=crlf" ;;
227         auto,)     echo "text=auto" ;;
228         auto,lf)   echo "text=auto eol=lf" ;;
229         auto,crlf) echo "text=auto eol=crlf" ;;
230         lf,)       echo "text eol=lf" ;;
231         crlf,)     echo "text eol=crlf" ;;
232         ,) echo "" ;;
233         *) echo invalid_attr "$1,$2" ;;
234         esac
235 }
236
237 check_files_in_repo () {
238         crlf=$1
239         attr=$2
240         lfname=$3
241         crlfname=$4
242         lfmixcrlf=$5
243         lfmixcr=$6
244         crlfnul=$7
245         pfx=crlf_${crlf}_attr_${attr}_ &&
246         compare_files $lfname ${pfx}LF.txt &&
247         compare_files $crlfname ${pfx}CRLF.txt &&
248         compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt &&
249         compare_files $lfmixcr ${pfx}LF_mix_CR.txt &&
250         compare_files $crlfnul ${pfx}CRLF_nul.txt
251 }
252
253 check_in_repo_NNO () {
254         attr=$1 ; shift
255         aeol=$1 ; shift
256         crlf=$1 ; shift
257         lfname=$1 ; shift
258         crlfname=$1 ; shift
259         lfmixcrlf=$1 ; shift
260         lfmixcr=$1 ; shift
261         crlfnul=$1 ; shift
262         pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
263         test_expect_success "compare_files $lfname ${pfx}_LF.txt" '
264                 compare_files $lfname ${pfx}_LF.txt
265         '
266         test_expect_success "compare_files $crlfname ${pfx}_CRLF.txt" '
267                 compare_files $crlfname ${pfx}_CRLF.txt
268         '
269         test_expect_success "compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt" '
270                 compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt
271         '
272         test_expect_success "compare_files $lfmixcr ${pfx}_LF_mix_CR.txt" '
273                 compare_files $lfmixcr ${pfx}_LF_mix_CR.txt
274         '
275         test_expect_success "compare_files $crlfnul ${pfx}_CRLF_nul.txt" '
276                 compare_files $crlfnul ${pfx}_CRLF_nul.txt
277         '
278 }
279
280 checkout_files () {
281         attr=$1 ; shift
282         ident=$1; shift
283         aeol=$1 ; shift
284         crlf=$1 ; shift
285         ceol=$1 ; shift
286         lfname=$1 ; shift
287         crlfname=$1 ; shift
288         lfmixcrlf=$1 ; shift
289         lfmixcr=$1 ; shift
290         crlfnul=$1 ; shift
291         create_gitattributes "$attr" $ident $aeol &&
292         git config core.autocrlf $crlf &&
293         pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
294         for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
295         do
296                 rm crlf_false_attr__$f.txt &&
297                 if test -z "$ceol"; then
298                         git checkout -- crlf_false_attr__$f.txt
299                 else
300                         git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
301                 fi
302         done
303
304         test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
305                 test_when_finished "rm expect actual" &&
306                 sort <<-EOF >expect &&
307                 i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt
308                 i/mixed w/$(stats_ascii $lfmixcrlf) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_mix_LF.txt
309                 i/lf w/$(stats_ascii $lfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF.txt
310                 i/-text w/$(stats_ascii $lfmixcr) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_mix_CR.txt
311                 i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_nul.txt
312                 i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_nul.txt
313                 EOF
314                 git ls-files --eol crlf_false_attr__* |
315                 sed -e "s/      / /g" -e "s/  */ /g" |
316                 sort >actual &&
317                 test_cmp expect actual
318         '
319         test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF" "
320                 compare_ws_file $pfx $lfname    crlf_false_attr__LF.txt
321         "
322         test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" "
323                 compare_ws_file $pfx $crlfname  crlf_false_attr__CRLF.txt
324         "
325         test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" "
326                 compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt
327         "
328         test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" "
329                 compare_ws_file $pfx $lfmixcr   crlf_false_attr__LF_mix_CR.txt
330         "
331         test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" "
332                 compare_ws_file $pfx $crlfnul   crlf_false_attr__LF_nul.txt
333         "
334 }
335
336 # Test control characters
337 # NUL SOH CR EOF==^Z
338 test_expect_success 'ls-files --eol -o Text/Binary' '
339         test_when_finished "rm expect actual TeBi_*" &&
340         STRT=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &&
341         STR=$STRT$STRT$STRT$STRT &&
342         printf "${STR}BBB\001" >TeBi_127_S &&
343         printf "${STR}BBBB\001">TeBi_128_S &&
344         printf "${STR}BBB\032" >TeBi_127_E &&
345         printf "\032${STR}BBB" >TeBi_E_127 &&
346         printf "${STR}BBBB\000">TeBi_128_N &&
347         printf "${STR}BBB\012">TeBi_128_L &&
348         printf "${STR}BBB\015">TeBi_127_C &&
349         printf "${STR}BB\015\012" >TeBi_126_CL &&
350         printf "${STR}BB\015\012\015" >TeBi_126_CLC &&
351         sort <<-\EOF >expect &&
352         i/ w/-text TeBi_127_S
353         i/ w/none TeBi_128_S
354         i/ w/none TeBi_127_E
355         i/ w/-text TeBi_E_127
356         i/ w/-text TeBi_128_N
357         i/ w/lf TeBi_128_L
358         i/ w/-text TeBi_127_C
359         i/ w/crlf TeBi_126_CL
360         i/ w/-text TeBi_126_CLC
361         EOF
362         git ls-files --eol -o |
363         sed -n -e "/TeBi_/{s!attr/[     ]*!!g
364         s!      ! !g
365         s!  *! !g
366         p
367         }" | sort >actual &&
368         test_cmp expect actual
369 '
370
371 test_expect_success 'setup main' '
372         echo >.gitattributes &&
373         git checkout -b main &&
374         git add .gitattributes &&
375         git commit -m "add .gitattributes" . &&
376         printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\nLINETHREE"     >LF &&
377         printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\r\nLINETHREE" >CRLF &&
378         printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\r\nLINETWO\nLINETHREE"   >CRLF_mix_LF &&
379         printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\rLINETHREE"     >LF_mix_CR &&
380         printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\rLINETHREE"   >CRLF_mix_CR &&
381         printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONEQ\r\nLINETWO\r\nLINETHREE" | q_to_nul >CRLF_nul &&
382         printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONEQ\nLINETWO\nLINETHREE" | q_to_nul >LF_nul &&
383         create_NNO_MIX_files &&
384         git -c core.autocrlf=false add NNO_*.txt MIX_*.txt &&
385         git commit -m "mixed line endings" &&
386         test_tick
387 '
388
389 # Disable extra chain-linting for the next set of tests. There are many
390 # auto-generated ones that are not worth checking over and over.
391 GIT_TEST_CHAIN_LINT_HARDER_DEFAULT=0
392
393 warn_LF_CRLF="LF will be replaced by CRLF"
394 warn_CRLF_LF="CRLF will be replaced by LF"
395
396 # WILC stands for "Warn if (this OS) converts LF into CRLF".
397 # WICL: Warn if CRLF becomes LF
398 # WAMIX: Mixed line endings: either CRLF->LF or LF->CRLF
399 if test_have_prereq NATIVE_CRLF
400 then
401         WILC=LF_CRLF
402         WICL=
403         WAMIX=LF_CRLF
404 else
405         WILC=
406         WICL=CRLF_LF
407         WAMIX=CRLF_LF
408 fi
409
410 #                         attr   LF        CRLF      CRLFmixLF LFmixCR   CRLFNUL
411 test_expect_success 'commit files empty attr' '
412         commit_check_warn false ""     ""        ""        ""        ""        "" &&
413         commit_check_warn true  ""     "LF_CRLF" ""        "LF_CRLF" ""        "" &&
414         commit_check_warn input ""     ""        "CRLF_LF" "CRLF_LF" ""        ""
415 '
416
417 test_expect_success 'commit files attr=auto' '
418         commit_check_warn false "auto" "$WILC"   "$WICL"   "$WAMIX"  ""        "" &&
419         commit_check_warn true  "auto" "LF_CRLF" ""        "LF_CRLF" ""        "" &&
420         commit_check_warn input "auto" ""        "CRLF_LF" "CRLF_LF" ""        ""
421 '
422
423 test_expect_success 'commit files attr=text' '
424         commit_check_warn false "text" "$WILC"   "$WICL"   "$WAMIX"  "$WILC"   "$WICL"   &&
425         commit_check_warn true  "text" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""        &&
426         commit_check_warn input "text" ""        "CRLF_LF" "CRLF_LF" ""        "CRLF_LF"
427 '
428
429 test_expect_success 'commit files attr=-text' '
430         commit_check_warn false "-text" ""       ""        ""        ""        "" &&
431         commit_check_warn true  "-text" ""       ""        ""        ""        "" &&
432         commit_check_warn input "-text" ""       ""        ""        ""        ""
433 '
434
435 test_expect_success 'commit files attr=lf' '
436         commit_check_warn false "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
437         commit_check_warn true  "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
438         commit_check_warn input "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF"
439 '
440
441 test_expect_success 'commit files attr=crlf' '
442         commit_check_warn false "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
443         commit_check_warn true  "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
444         commit_check_warn input "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""
445 '
446
447 # Commit "CRLFmixLF" on top of these files already in the repo:
448 #                                         mixed     mixed     mixed       mixed       mixed
449 #                                         onto      onto      onto        onto        onto
450 #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
451 commit_MIX_chkwrn ""      ""      false   ""        ""        ""          ""          ""
452 commit_MIX_chkwrn ""      ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
453 commit_MIX_chkwrn ""      ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
454
455 commit_MIX_chkwrn "auto"  ""      false   "$WAMIX"  ""        ""          "$WAMIX"    "$WAMIX"
456 commit_MIX_chkwrn "auto"  ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
457 commit_MIX_chkwrn "auto"  ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
458
459 #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
460 commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
461 commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""
462 commit_chk_wrnNNO ""      ""      input   ""        ""        ""          ""          ""
463
464 commit_chk_wrnNNO "auto"  ""      false   "$WILC"   ""        ""          ""          ""
465 commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        ""          ""          ""
466 commit_chk_wrnNNO "auto"  ""      input   ""        ""        ""          ""          ""
467 for crlf in true false input
468 do
469         commit_chk_wrnNNO -text ""      $crlf   ""        ""        ""          ""          ""
470         commit_chk_wrnNNO -text lf      $crlf   ""        ""        ""          ""          ""
471         commit_chk_wrnNNO -text crlf    $crlf   ""        ""        ""          ""          ""
472         commit_chk_wrnNNO ""    lf      $crlf   ""       CRLF_LF    CRLF_LF      ""         CRLF_LF
473         commit_chk_wrnNNO ""    crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
474         commit_chk_wrnNNO auto  lf      $crlf   ""        ""        ""          ""          ""
475         commit_chk_wrnNNO auto  crlf    $crlf   LF_CRLF   ""        ""          ""          ""
476         commit_chk_wrnNNO text  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
477         commit_chk_wrnNNO text  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
478 done
479
480 commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
481 commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
482 commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
483
484 test_expect_success 'commit NNO and cleanup' '
485         git commit -m "commit files on top of NNO" &&
486         rm -f *.txt &&
487         git -c core.autocrlf=false reset --hard
488 '
489
490 test_expect_success 'commit empty gitattribues' '
491         check_files_in_repo false ""      LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
492         check_files_in_repo true  ""      LF LF   LF          LF_mix_CR CRLF_nul &&
493         check_files_in_repo input ""      LF LF   LF          LF_mix_CR CRLF_nul
494 '
495
496 test_expect_success 'commit text=auto' '
497         check_files_in_repo false "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
498         check_files_in_repo true  "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
499         check_files_in_repo input "auto"  LF LF   LF          LF_mix_CR CRLF_nul
500 '
501
502 test_expect_success 'commit text' '
503         check_files_in_repo false "text"  LF LF   LF          LF_mix_CR LF_nul &&
504         check_files_in_repo true  "text"  LF LF   LF          LF_mix_CR LF_nul &&
505         check_files_in_repo input "text"  LF LF   LF          LF_mix_CR LF_nul
506 '
507
508 test_expect_success 'commit -text' '
509         check_files_in_repo false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
510         check_files_in_repo true  "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
511         check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
512 '
513
514 for crlf in true false input
515 do
516         #                 attr  aeol           LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLFNUL
517         check_in_repo_NNO ""    ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
518         check_in_repo_NNO -text ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
519         check_in_repo_NNO -text lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
520         check_in_repo_NNO -text crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
521         check_in_repo_NNO auto  ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
522         check_in_repo_NNO auto  lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
523         check_in_repo_NNO auto  crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
524         check_in_repo_NNO text  ""     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
525         check_in_repo_NNO text  lf     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
526         check_in_repo_NNO text  crlf   $crlf   LF  LF    LF           LF_mix_CR  LF_nul
527 done
528 ################################################################################
529 # Check how files in the repo are changed when they are checked out
530 # How to read the table below:
531 # - checkout_files will check multiple files with a combination of settings
532 #   and attributes (core.autocrlf=input is forbidden with core.eol=crlf)
533 #
534 # - parameter $1        : text in .gitattributs  "" (empty) | auto | text | -text
535 # - parameter $2        : ident                  "" | i (i == ident)
536 # - parameter $3        : eol in .gitattributs   "" (empty) | lf | crlf
537 # - parameter $4        : core.autocrlf          false | true | input
538 # - parameter $5        : core.eol               "" | lf | crlf | "native"
539 # - parameter $6        : reference for a file with only LF in the repo
540 # - parameter $7        : reference for a file with only CRLF in the repo
541 # - parameter $8        : reference for a file with mixed LF and CRLF in the repo
542 # - parameter $9        : reference for a file with LF and CR in the repo
543 # - parameter $10 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
544
545 if test_have_prereq NATIVE_CRLF
546 then
547 MIX_CRLF_LF=CRLF
548 MIX_LF_CR=CRLF_mix_CR
549 NL=CRLF
550 LFNUL=CRLF_nul
551 else
552 MIX_CRLF_LF=CRLF_mix_LF
553 MIX_LF_CR=LF_mix_CR
554 NL=LF
555 LFNUL=LF_nul
556 fi
557 export CRLF_MIX_LF_CR MIX NL
558
559 # Same handling with and without ident
560 for id in "" ident
561 do
562         for ceol in lf crlf native
563         do
564                 for crlf in true false input
565                 do
566                         # -text overrides core.autocrlf and core.eol
567                         # text and eol=crlf or eol=lf override core.autocrlf and core.eol
568                         checkout_files -text "$id" ""     "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
569                         checkout_files -text "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
570                         checkout_files -text "$id" "crlf" "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
571                         # text
572                         checkout_files text  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
573                         checkout_files text  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
574                         # currently the same as text, eol=XXX
575                         checkout_files auto  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
576                         checkout_files auto  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
577                 done
578
579                 # core.autocrlf false, different core.eol
580                 checkout_files   ""    "$id" ""     false   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
581                 # core.autocrlf true
582                 checkout_files   ""    "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
583                 # text: core.autocrlf = true overrides core.eol
584                 checkout_files   auto  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
585                 checkout_files   text  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
586                 # text: core.autocrlf = input overrides core.eol
587                 checkout_files   text  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
588                 checkout_files   auto  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
589                 # text=auto + eol=XXX
590         done
591         # text: core.autocrlf=false uses core.eol
592         checkout_files     text  "$id" ""     false   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
593         checkout_files     text  "$id" ""     false   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
594         # text: core.autocrlf=false and core.eol unset(or native) uses native eol
595         checkout_files     text  "$id" ""     false   ""       $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
596         checkout_files     text  "$id" ""     false   native   $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
597         # auto: core.autocrlf=false and core.eol unset(or native) uses native eol
598         checkout_files     auto  "$id" ""     false   ""       $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
599         checkout_files     auto  "$id" ""     false   native   $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
600 done
601
602 # The rest of the tests are unique; do the usual linting.
603 unset GIT_TEST_CHAIN_LINT_HARDER_DEFAULT
604
605 # Should be the last test case: remove some files from the worktree
606 test_expect_success 'ls-files --eol -d -z' '
607         rm crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
608         cat >expect <<-\EOF &&
609         i/crlf w/ crlf_false_attr__CRLF.txt
610         i/lf w/ .gitattributes
611         i/lf w/ crlf_false_attr__LF.txt
612         i/mixed w/ crlf_false_attr__CRLF_mix_LF.txt
613         EOF
614         git ls-files --eol -d |
615         sed -e "s!attr/[^       ]*!!g" -e "s/   / /g" -e "s/  */ /g" |
616         sort >actual &&
617         test_cmp expect actual
618 '
619
620 test_done