t / t0027-auto-crlf.shon commit t4045: abstract away SHA-1-specific constants (5c02428)
   1#!/bin/sh
   2
   3test_description='CRLF conversion all combinations'
   4
   5. ./test-lib.sh
   6
   7compare_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
  14compare_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
  24create_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.
  52create_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
  76check_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
  87commit_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
 111commit_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
 153commit_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
 194stats_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
 219attr_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
 235check_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
 251check_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
 278checkout_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
 336test_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
 369test_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
 389warn_LF_CRLF="LF will be replaced by CRLF"
 390warn_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
 395if test_have_prereq NATIVE_CRLF
 396then
 397        WILC=LF_CRLF
 398        WICL=
 399        WAMIX=LF_CRLF
 400else
 401        WILC=
 402        WICL=CRLF_LF
 403        WAMIX=CRLF_LF
 404fi
 405
 406#                         attr   LF        CRLF      CRLFmixLF LFmixCR   CRLFNUL
 407test_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
 413test_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
 419test_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
 425test_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
 431test_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
 437test_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
 447commit_MIX_chkwrn ""      ""      false   ""        ""        ""          ""          ""
 448commit_MIX_chkwrn ""      ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
 449commit_MIX_chkwrn ""      ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
 450
 451commit_MIX_chkwrn "auto"  ""      false   "$WAMIX"  ""        ""          "$WAMIX"    "$WAMIX"
 452commit_MIX_chkwrn "auto"  ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
 453commit_MIX_chkwrn "auto"  ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
 454
 455#                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
 456commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
 457commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""
 458commit_chk_wrnNNO ""      ""      input   ""        ""        ""          ""          ""
 459
 460commit_chk_wrnNNO "auto"  ""      false   "$WILC"   ""        ""          ""          ""
 461commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        ""          ""          ""
 462commit_chk_wrnNNO "auto"  ""      input   ""        ""        ""          ""          ""
 463for crlf in true false input
 464do
 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     ""
 474done
 475
 476commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
 477commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 478commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
 479
 480test_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
 486test_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
 492test_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
 498test_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
 504test_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
 510for crlf in true false input
 511do
 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
 523done
 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
 541if test_have_prereq NATIVE_CRLF
 542then
 543MIX_CRLF_LF=CRLF
 544MIX_LF_CR=CRLF_mix_CR
 545NL=CRLF
 546LFNUL=CRLF_nul
 547else
 548MIX_CRLF_LF=CRLF_mix_LF
 549MIX_LF_CR=LF_mix_CR
 550NL=LF
 551LFNUL=LF_nul
 552fi
 553export CRLF_MIX_LF_CR MIX NL
 554
 555# Same handling with and without ident
 556for id in "" ident
 557do
 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
 596done
 597
 598# Should be the last test case: remove some files from the worktree
 599test_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
 613test_done