Merge branch 'ss/faq-fetch-pull'
[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_i18ncmp "$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 master' '
372         echo >.gitattributes &&
373         git checkout -b master &&
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
390
391 warn_LF_CRLF="LF will be replaced by CRLF"
392 warn_CRLF_LF="CRLF will be replaced by LF"
393
394 # WILC stands for "Warn if (this OS) converts LF into CRLF".
395 # WICL: Warn if CRLF becomes LF
396 # WAMIX: Mixed line endings: either CRLF->LF or LF->CRLF
397 if test_have_prereq NATIVE_CRLF
398 then
399         WILC=LF_CRLF
400         WICL=
401         WAMIX=LF_CRLF
402 else
403         WILC=
404         WICL=CRLF_LF
405         WAMIX=CRLF_LF
406 fi
407
408 #                         attr   LF        CRLF      CRLFmixLF LFmixCR   CRLFNUL
409 test_expect_success 'commit files empty attr' '
410         commit_check_warn false ""     ""        ""        ""        ""        "" &&
411         commit_check_warn true  ""     "LF_CRLF" ""        "LF_CRLF" ""        "" &&
412         commit_check_warn input ""     ""        "CRLF_LF" "CRLF_LF" ""        ""
413 '
414
415 test_expect_success 'commit files attr=auto' '
416         commit_check_warn false "auto" "$WILC"   "$WICL"   "$WAMIX"  ""        "" &&
417         commit_check_warn true  "auto" "LF_CRLF" ""        "LF_CRLF" ""        "" &&
418         commit_check_warn input "auto" ""        "CRLF_LF" "CRLF_LF" ""        ""
419 '
420
421 test_expect_success 'commit files attr=text' '
422         commit_check_warn false "text" "$WILC"   "$WICL"   "$WAMIX"  "$WILC"   "$WICL"   &&
423         commit_check_warn true  "text" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""        &&
424         commit_check_warn input "text" ""        "CRLF_LF" "CRLF_LF" ""        "CRLF_LF"
425 '
426
427 test_expect_success 'commit files attr=-text' '
428         commit_check_warn false "-text" ""       ""        ""        ""        "" &&
429         commit_check_warn true  "-text" ""       ""        ""        ""        "" &&
430         commit_check_warn input "-text" ""       ""        ""        ""        ""
431 '
432
433 test_expect_success 'commit files attr=lf' '
434         commit_check_warn false "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
435         commit_check_warn true  "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
436         commit_check_warn input "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF"
437 '
438
439 test_expect_success 'commit files attr=crlf' '
440         commit_check_warn false "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
441         commit_check_warn true  "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
442         commit_check_warn input "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""
443 '
444
445 # Commit "CRLFmixLF" on top of these files already in the repo:
446 #                                         mixed     mixed     mixed       mixed       mixed
447 #                                         onto      onto      onto        onto        onto
448 #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
449 commit_MIX_chkwrn ""      ""      false   ""        ""        ""          ""          ""
450 commit_MIX_chkwrn ""      ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
451 commit_MIX_chkwrn ""      ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
452
453 commit_MIX_chkwrn "auto"  ""      false   "$WAMIX"  ""        ""          "$WAMIX"    "$WAMIX"
454 commit_MIX_chkwrn "auto"  ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
455 commit_MIX_chkwrn "auto"  ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
456
457 #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
458 commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
459 commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""
460 commit_chk_wrnNNO ""      ""      input   ""        ""        ""          ""          ""
461
462 commit_chk_wrnNNO "auto"  ""      false   "$WILC"   ""        ""          ""          ""
463 commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        ""          ""          ""
464 commit_chk_wrnNNO "auto"  ""      input   ""        ""        ""          ""          ""
465 for crlf in true false input
466 do
467         commit_chk_wrnNNO -text ""      $crlf   ""        ""        ""          ""          ""
468         commit_chk_wrnNNO -text lf      $crlf   ""        ""        ""          ""          ""
469         commit_chk_wrnNNO -text crlf    $crlf   ""        ""        ""          ""          ""
470         commit_chk_wrnNNO ""    lf      $crlf   ""       CRLF_LF    CRLF_LF      ""         CRLF_LF
471         commit_chk_wrnNNO ""    crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
472         commit_chk_wrnNNO auto  lf      $crlf   ""        ""        ""          ""          ""
473         commit_chk_wrnNNO auto  crlf    $crlf   LF_CRLF   ""        ""          ""          ""
474         commit_chk_wrnNNO text  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
475         commit_chk_wrnNNO text  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
476 done
477
478 commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
479 commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
480 commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
481
482 test_expect_success 'commit NNO and cleanup' '
483         git commit -m "commit files on top of NNO" &&
484         rm -f *.txt &&
485         git -c core.autocrlf=false reset --hard
486 '
487
488 test_expect_success 'commit empty gitattribues' '
489         check_files_in_repo false ""      LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
490         check_files_in_repo true  ""      LF LF   LF          LF_mix_CR CRLF_nul &&
491         check_files_in_repo input ""      LF LF   LF          LF_mix_CR CRLF_nul
492 '
493
494 test_expect_success 'commit text=auto' '
495         check_files_in_repo false "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
496         check_files_in_repo true  "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
497         check_files_in_repo input "auto"  LF LF   LF          LF_mix_CR CRLF_nul
498 '
499
500 test_expect_success 'commit text' '
501         check_files_in_repo false "text"  LF LF   LF          LF_mix_CR LF_nul &&
502         check_files_in_repo true  "text"  LF LF   LF          LF_mix_CR LF_nul &&
503         check_files_in_repo input "text"  LF LF   LF          LF_mix_CR LF_nul
504 '
505
506 test_expect_success 'commit -text' '
507         check_files_in_repo false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
508         check_files_in_repo true  "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
509         check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
510 '
511
512 for crlf in true false input
513 do
514         #                 attr  aeol           LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLFNUL
515         check_in_repo_NNO ""    ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
516         check_in_repo_NNO -text ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
517         check_in_repo_NNO -text lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
518         check_in_repo_NNO -text crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
519         check_in_repo_NNO auto  ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
520         check_in_repo_NNO auto  lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
521         check_in_repo_NNO auto  crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
522         check_in_repo_NNO text  ""     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
523         check_in_repo_NNO text  lf     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
524         check_in_repo_NNO text  crlf   $crlf   LF  LF    LF           LF_mix_CR  LF_nul
525 done
526 ################################################################################
527 # Check how files in the repo are changed when they are checked out
528 # How to read the table below:
529 # - checkout_files will check multiple files with a combination of settings
530 #   and attributes (core.autocrlf=input is forbidden with core.eol=crlf)
531 #
532 # - parameter $1        : text in .gitattributs  "" (empty) | auto | text | -text
533 # - parameter $2        : ident                  "" | i (i == ident)
534 # - parameter $3        : eol in .gitattributs   "" (empty) | lf | crlf
535 # - parameter $4        : core.autocrlf          false | true | input
536 # - parameter $5        : core.eol               "" | lf | crlf | "native"
537 # - parameter $6        : reference for a file with only LF in the repo
538 # - parameter $7        : reference for a file with only CRLF in the repo
539 # - parameter $8        : reference for a file with mixed LF and CRLF in the repo
540 # - parameter $9        : reference for a file with LF and CR in the repo
541 # - parameter $10 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
542
543 if test_have_prereq NATIVE_CRLF
544 then
545 MIX_CRLF_LF=CRLF
546 MIX_LF_CR=CRLF_mix_CR
547 NL=CRLF
548 LFNUL=CRLF_nul
549 else
550 MIX_CRLF_LF=CRLF_mix_LF
551 MIX_LF_CR=LF_mix_CR
552 NL=LF
553 LFNUL=LF_nul
554 fi
555 export CRLF_MIX_LF_CR MIX NL
556
557 # Same handling with and without ident
558 for id in "" ident
559 do
560         for ceol in lf crlf native
561         do
562                 for crlf in true false input
563                 do
564                         # -text overrides core.autocrlf and core.eol
565                         # text and eol=crlf or eol=lf override core.autocrlf and core.eol
566                         checkout_files -text "$id" ""     "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
567                         checkout_files -text "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
568                         checkout_files -text "$id" "crlf" "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
569                         # text
570                         checkout_files text  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
571                         checkout_files text  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
572                         # currently the same as text, eol=XXX
573                         checkout_files auto  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
574                         checkout_files auto  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
575                 done
576
577                 # core.autocrlf false, different core.eol
578                 checkout_files   ""    "$id" ""     false   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
579                 # core.autocrlf true
580                 checkout_files   ""    "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
581                 # text: core.autocrlf = true overrides core.eol
582                 checkout_files   auto  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
583                 checkout_files   text  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
584                 # text: core.autocrlf = input overrides core.eol
585                 checkout_files   text  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
586                 checkout_files   auto  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
587                 # text=auto + eol=XXX
588         done
589         # text: core.autocrlf=false uses core.eol
590         checkout_files     text  "$id" ""     false   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
591         checkout_files     text  "$id" ""     false   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
592         # text: core.autocrlf=false and core.eol unset(or native) uses native eol
593         checkout_files     text  "$id" ""     false   ""       $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
594         checkout_files     text  "$id" ""     false   native   $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
595         # auto: core.autocrlf=false and core.eol unset(or native) uses native eol
596         checkout_files     auto  "$id" ""     false   ""       $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
597         checkout_files     auto  "$id" ""     false   native   $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
598 done
599
600 # Should be the last test case: remove some files from the worktree
601 test_expect_success 'ls-files --eol -d -z' '
602         rm crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
603         cat >expect <<-\EOF &&
604         i/crlf w/ crlf_false_attr__CRLF.txt
605         i/lf w/ .gitattributes
606         i/lf w/ crlf_false_attr__LF.txt
607         i/mixed w/ crlf_false_attr__CRLF_mix_LF.txt
608         EOF
609         git ls-files --eol -d |
610         sed -e "s!attr/[^       ]*!!g" -e "s/   / /g" -e "s/  */ /g" |
611         sort >actual &&
612         test_cmp expect actual
613 '
614
615 test_done