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