3 test_description='CRLF conversion all combinations'
7 if ! test_have_prereq EXPENSIVE
9 skip_all="EXPENSIVE not set"
14 tr '\015\000' QN <"$1" >"$1".expect &&
15 tr '\015\000' QN <"$2" >"$2".actual &&
16 test_cmp "$1".expect "$2".actual &&
17 rm "$1".expect "$2".actual
24 tr '\015\000' QN <"$2" >"$exp" &&
25 tr '\015\000' QN <"$3" >"$act" &&
30 create_gitattributes () {
34 echo "*.txt text=auto" >.gitattributes
37 echo "*.txt text" >.gitattributes
40 echo "*.txt -text" >.gitattributes
43 echo "*.txt eol=crlf" >.gitattributes
46 echo "*.txt eol=lf" >.gitattributes
52 echo >&2 invalid attribute: $attr
64 for crlf in false true input
66 for attr in "" auto text -text lf crlf
68 pfx=NNO_${crlf}_attr_${attr} &&
69 cp $lfname ${pfx}_LF.txt &&
70 cp $crlfname ${pfx}_CRLF.txt &&
71 cp $lfmixcrlf ${pfx}_CRLF_mix_LF.txt &&
72 cp $lfmixcr ${pfx}_LF_mix_CR.txt &&
73 cp $crlfnul ${pfx}_CRLF_nul.txt
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 ;;
83 *) echo >&2 "Illegal 1": "$1" ; return false ;;
85 grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq >"$2".actual
86 test_cmp "$2".expect "$2".actual
89 commit_check_warn () {
97 pfx=crlf_${crlf}_attr_${attr}
98 create_gitattributes "$attr" &&
99 for f in LF CRLF repoMIX LF_mix_CR CRLF_mix_LF LF_nul CRLF_nul
101 fname=${pfx}_$f.txt &&
103 git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
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
113 commit_chk_wrnNNO () {
121 pfx=NNO_${crlf}_attr_${attr}
122 #Commit files on top of existing file
123 create_gitattributes "$attr" &&
124 for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
126 fname=${pfx}_$f.txt &&
128 git -c core.autocrlf=$crlf add $fname 2>/dev/null &&
129 git -c core.autocrlf=$crlf commit -m "commit_$fname" $fname >"${pfx}_$f.err" 2>&1
132 test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
133 check_warning "$lfwarn" ${pfx}_LF.err
135 test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF" '
136 check_warning "$crlfwarn" ${pfx}_CRLF.err
139 test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_mix_LF" '
140 check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
143 test_expect_success "commit NNO files crlf=$crlf attr=$attr LF_mix_cr" '
144 check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
147 test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_nul" '
148 check_warning "$crlfnul" ${pfx}_CRLF_nul.err
152 check_files_in_repo () {
160 pfx=crlf_${crlf}_attr_${attr}_ &&
161 compare_files $lfname ${pfx}LF.txt &&
162 compare_files $crlfname ${pfx}CRLF.txt &&
163 compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt &&
164 compare_files $lfmixcr ${pfx}LF_mix_CR.txt &&
165 compare_files $crlfnul ${pfx}CRLF_nul.txt
168 check_in_repo_NNO () {
176 pfx=NNO_${crlf}_attr_${attr}_
177 test_expect_success "compare_files $lfname ${pfx}LF.txt" '
178 compare_files $lfname ${pfx}LF.txt
180 test_expect_success "compare_files $crlfname ${pfx}CRLF.txt" '
181 compare_files $crlfname ${pfx}CRLF.txt
183 test_expect_success "compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt" '
184 compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt
186 test_expect_success "compare_files $lfmixcr ${pfx}LF_mix_CR.txt" '
187 compare_files $lfmixcr ${pfx}LF_mix_CR.txt
189 test_expect_success "compare_files $crlfnul ${pfx}CRLF_nul.txt" '
190 compare_files $crlfnul ${pfx}CRLF_nul.txt
203 create_gitattributes $attr &&
204 git config core.autocrlf $crlf &&
205 pfx=eol_${eol}_crlf_${crlf}_attr_${attr}_ &&
206 src=crlf_false_attr__ &&
207 for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
210 if test -z "$eol"; then
211 git checkout $src$f.txt
213 git -c core.eol=$eol checkout $src$f.txt
217 test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF" "
218 compare_ws_file $pfx $lfname ${src}LF.txt
220 test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=CRLF" "
221 compare_ws_file $pfx $crlfname ${src}CRLF.txt
223 test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=CRLF_mix_LF" "
224 compare_ws_file $pfx $lfmixcrlf ${src}CRLF_mix_LF.txt
226 test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_mix_CR" "
227 compare_ws_file $pfx $lfmixcr ${src}LF_mix_CR.txt
229 test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_nul" "
230 compare_ws_file $pfx $crlfnul ${src}LF_nul.txt
235 test_expect_success 'setup master' '
236 echo >.gitattributes &&
237 git checkout -b master &&
238 git add .gitattributes &&
239 git commit -m "add .gitattributes" "" &&
240 printf "line1\nline2\nline3" >LF &&
241 printf "line1\r\nline2\r\nline3" >CRLF &&
242 printf "line1\r\nline2\nline3" >repoMIX &&
243 printf "line1\r\nline2\nline3" >CRLF_mix_LF &&
244 printf "line1\nline2\rline3" >LF_mix_CR &&
245 printf "line1\r\nline2\rline3" >CRLF_mix_CR &&
246 printf "line1Q\r\nline2\r\nline3" | q_to_nul >CRLF_nul &&
247 printf "line1Q\nline2\nline3" | q_to_nul >LF_nul &&
248 create_NNO_files CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF &&
249 git -c core.autocrlf=false add NNO_*.txt &&
250 git commit -m "mixed line endings" &&
256 warn_LF_CRLF="LF will be replaced by CRLF"
257 warn_CRLF_LF="CRLF will be replaced by LF"
259 # WILC stands for "Warn if (this OS) converts LF into CRLF".
260 # WICL: Warn if CRLF becomes LF
261 # WAMIX: Mixed line endings: either CRLF->LF or LF->CRLF
262 if test_have_prereq NATIVE_CRLF
273 # attr LF CRLF CRLFmixLF LFmixCR CRLFNUL
274 test_expect_success 'commit files empty attr' '
275 commit_check_warn false "" "" "" "" "" "" &&
276 commit_check_warn true "" "LF_CRLF" "" "LF_CRLF" "" "" &&
277 commit_check_warn input "" "" "CRLF_LF" "CRLF_LF" "" ""
280 test_expect_success 'commit files attr=auto' '
281 commit_check_warn false "auto" "$WILC" "$WICL" "$WAMIX" "" "" &&
282 commit_check_warn true "auto" "LF_CRLF" "" "LF_CRLF" "" "" &&
283 commit_check_warn input "auto" "" "CRLF_LF" "CRLF_LF" "" ""
286 test_expect_success 'commit files attr=text' '
287 commit_check_warn false "text" "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" &&
288 commit_check_warn true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" &&
289 commit_check_warn input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
292 test_expect_success 'commit files attr=-text' '
293 commit_check_warn false "-text" "" "" "" "" "" &&
294 commit_check_warn true "-text" "" "" "" "" "" &&
295 commit_check_warn input "-text" "" "" "" "" ""
298 test_expect_success 'commit files attr=lf' '
299 commit_check_warn false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" &&
300 commit_check_warn true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" &&
301 commit_check_warn input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
304 test_expect_success 'commit files attr=crlf' '
305 commit_check_warn false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" &&
306 commit_check_warn true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" &&
307 commit_check_warn input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" ""
310 # attr LF CRLF CRLFmixLF LF_mix_CR CRLFNUL
311 commit_chk_wrnNNO false "" "" "" "" "" ""
312 commit_chk_wrnNNO true "" "LF_CRLF" "" "" "" ""
313 commit_chk_wrnNNO input "" "" "" "" "" ""
316 commit_chk_wrnNNO false "auto" "$WILC" "$WICL" "$WAMIX" "" ""
317 commit_chk_wrnNNO true "auto" "LF_CRLF" "" "LF_CRLF" "" ""
318 commit_chk_wrnNNO input "auto" "" "CRLF_LF" "CRLF_LF" "" ""
320 commit_chk_wrnNNO false "text" "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL"
321 commit_chk_wrnNNO true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" ""
322 commit_chk_wrnNNO input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
324 commit_chk_wrnNNO false "-text" "" "" "" "" ""
325 commit_chk_wrnNNO true "-text" "" "" "" "" ""
326 commit_chk_wrnNNO input "-text" "" "" "" "" ""
328 commit_chk_wrnNNO false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
329 commit_chk_wrnNNO true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
330 commit_chk_wrnNNO input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF"
332 commit_chk_wrnNNO false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" ""
333 commit_chk_wrnNNO true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" ""
334 commit_chk_wrnNNO input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" ""
336 test_expect_success 'create files cleanup' '
338 git -c core.autocrlf=false reset --hard
341 test_expect_success 'commit empty gitattribues' '
342 check_files_in_repo false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
343 check_files_in_repo true "" LF LF LF LF_mix_CR CRLF_nul &&
344 check_files_in_repo input "" LF LF LF LF_mix_CR CRLF_nul
347 test_expect_success 'commit text=auto' '
348 check_files_in_repo false "auto" LF LF LF LF_mix_CR CRLF_nul &&
349 check_files_in_repo true "auto" LF LF LF LF_mix_CR CRLF_nul &&
350 check_files_in_repo input "auto" LF LF LF LF_mix_CR CRLF_nul
353 test_expect_success 'commit text' '
354 check_files_in_repo false "text" LF LF LF LF_mix_CR LF_nul &&
355 check_files_in_repo true "text" LF LF LF LF_mix_CR LF_nul &&
356 check_files_in_repo input "text" LF LF LF LF_mix_CR LF_nul
359 test_expect_success 'commit -text' '
360 check_files_in_repo false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
361 check_files_in_repo true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
362 check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
365 # attr LF CRLF CRLF_mix_LF LF_mix_CR CRLFNUL
366 check_in_repo_NNO false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
367 check_in_repo_NNO true "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
368 check_in_repo_NNO input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
370 check_in_repo_NNO false "auto" LF LF LF LF_mix_CR CRLF_nul
371 check_in_repo_NNO true "auto" LF LF LF LF_mix_CR CRLF_nul
372 check_in_repo_NNO input "auto" LF LF LF LF_mix_CR CRLF_nul
374 check_in_repo_NNO false "text" LF LF LF LF_mix_CR LF_nul
375 check_in_repo_NNO true "text" LF LF LF LF_mix_CR LF_nul
376 check_in_repo_NNO input "text" LF LF LF LF_mix_CR LF_nul
378 check_in_repo_NNO false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
379 check_in_repo_NNO true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
380 check_in_repo_NNO input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
383 ################################################################################
384 # Check how files in the repo are changed when they are checked out
385 # How to read the table below:
386 # - checkout_files will check multiple files with a combination of settings
387 # and attributes (core.autocrlf=input is forbidden with core.eol=crlf)
388 # - parameter $1 : core.eol lf | crlf
389 # - parameter $2 : core.autocrlf false | true | input
390 # - parameter $3 : text in .gitattributs "" (empty) | auto | text | -text
391 # - parameter $4 : reference for a file with only LF in the repo
392 # - parameter $5 : reference for a file with only CRLF in the repo
393 # - parameter $6 : reference for a file with mixed LF and CRLF in the repo
394 # - parameter $7 : reference for a file with LF and CR in the repo (does somebody uses this ?)
395 # - parameter $8 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
397 # What we have in the repo:
398 # ----------------- EOL in repo ----------------
399 # LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
400 # settings with checkout:
401 # core. core. .gitattr
403 # ----------------------------------------------
404 # What we want to have in the working tree:
405 if test_have_prereq NATIVE_CRLF
408 MIX_LF_CR=CRLF_mix_CR
412 MIX_CRLF_LF=CRLF_mix_LF
417 export CRLF_MIX_LF_CR MIX NL
419 checkout_files lf false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
420 checkout_files lf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
421 checkout_files lf input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
422 checkout_files lf false "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
423 checkout_files lf true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
424 checkout_files lf input "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
425 checkout_files lf false "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
426 checkout_files lf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
427 checkout_files lf input "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
428 checkout_files lf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
429 checkout_files lf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
430 checkout_files lf input "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
431 checkout_files lf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
432 checkout_files lf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
433 checkout_files lf input "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
434 checkout_files lf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
435 checkout_files lf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
436 checkout_files lf input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
438 checkout_files crlf false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
439 checkout_files crlf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
440 checkout_files crlf false "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
441 checkout_files crlf true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
442 checkout_files crlf false "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
443 checkout_files crlf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
444 checkout_files crlf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
445 checkout_files crlf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
446 checkout_files crlf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
447 checkout_files crlf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
448 checkout_files crlf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
449 checkout_files crlf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
451 checkout_files "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
452 checkout_files "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
453 checkout_files "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
454 checkout_files "" false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
455 checkout_files "" true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
456 checkout_files "" input "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
457 checkout_files "" false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
458 checkout_files "" true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
459 checkout_files "" input "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
460 checkout_files "" false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
461 checkout_files "" true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
462 checkout_files "" input "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
463 checkout_files "" false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
464 checkout_files "" true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
465 checkout_files "" input "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
466 checkout_files "" false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
467 checkout_files "" true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
468 checkout_files "" input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
470 checkout_files native false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
471 checkout_files native true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
472 checkout_files native false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
473 checkout_files native true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
474 checkout_files native false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
475 checkout_files native true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
476 checkout_files native false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
477 checkout_files native true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
478 checkout_files native false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
479 checkout_files native true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
480 checkout_files native false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
481 checkout_files native true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul