t / t0027-auto-crlf.shon commit Merge branch 'ak/t4204-shell-portability' (b586d8c)
   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 "" ident
 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