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