t / t0027-auto-crlf.shon commit Merge branch 'jc/renormalize-merge-kill-safer-crlf' into maint (7f5885a)
   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=auto eol=lf" ;;
 179        auto,crlf) echo "text=auto 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"   ""        ""          ""          ""
 401commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        ""          ""          ""
 402commit_chk_wrnNNO "auto"  ""      input   ""        ""        ""          ""          ""
 403for crlf in true false input
 404do
 405        commit_chk_wrnNNO -text ""      $crlf   ""        ""        ""          ""          ""
 406        commit_chk_wrnNNO -text lf      $crlf   ""        ""        ""          ""          ""
 407        commit_chk_wrnNNO -text crlf    $crlf   ""        ""        ""          ""          ""
 408        commit_chk_wrnNNO ""    lf      $crlf   ""       CRLF_LF    CRLF_LF      ""         CRLF_LF
 409        commit_chk_wrnNNO ""    crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 410        commit_chk_wrnNNO auto  lf      $crlf   ""        ""        ""          ""          ""
 411        commit_chk_wrnNNO auto  crlf    $crlf   LF_CRLF   ""        ""          ""          ""
 412        commit_chk_wrnNNO text  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
 413        commit_chk_wrnNNO text  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 414done
 415
 416commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
 417commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 418commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
 419
 420test_expect_success 'create files cleanup' '
 421        rm -f *.txt &&
 422        git -c core.autocrlf=false reset --hard
 423'
 424
 425test_expect_success 'commit empty gitattribues' '
 426        check_files_in_repo false ""      LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
 427        check_files_in_repo true  ""      LF LF   LF          LF_mix_CR CRLF_nul &&
 428        check_files_in_repo input ""      LF LF   LF          LF_mix_CR CRLF_nul
 429'
 430
 431test_expect_success 'commit text=auto' '
 432        check_files_in_repo false "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
 433        check_files_in_repo true  "auto"  LF LF   LF          LF_mix_CR CRLF_nul &&
 434        check_files_in_repo input "auto"  LF LF   LF          LF_mix_CR CRLF_nul
 435'
 436
 437test_expect_success 'commit text' '
 438        check_files_in_repo false "text"  LF LF   LF          LF_mix_CR LF_nul &&
 439        check_files_in_repo true  "text"  LF LF   LF          LF_mix_CR LF_nul &&
 440        check_files_in_repo input "text"  LF LF   LF          LF_mix_CR LF_nul
 441'
 442
 443test_expect_success 'commit -text' '
 444        check_files_in_repo false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
 445        check_files_in_repo true  "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
 446        check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
 447'
 448
 449for crlf in true false input
 450do
 451        #                 attr  aeol           LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLFNUL
 452        check_in_repo_NNO ""    ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 453        check_in_repo_NNO -text ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 454        check_in_repo_NNO -text lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 455        check_in_repo_NNO -text crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 456        check_in_repo_NNO auto  ""     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 457        check_in_repo_NNO auto  lf     $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 458        check_in_repo_NNO auto  crlf   $crlf   LF  CRLF  CRLF_mix_LF  LF_mix_CR  CRLF_nul
 459        check_in_repo_NNO text  ""     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
 460        check_in_repo_NNO text  lf     $crlf   LF  LF    LF           LF_mix_CR  LF_nul
 461        check_in_repo_NNO text  crlf   $crlf   LF  LF    LF           LF_mix_CR  LF_nul
 462done
 463################################################################################
 464# Check how files in the repo are changed when they are checked out
 465# How to read the table below:
 466# - checkout_files will check multiple files with a combination of settings
 467#   and attributes (core.autocrlf=input is forbidden with core.eol=crlf)
 468#
 469# - parameter $1        : text in .gitattributs  "" (empty) | auto | text | -text
 470# - parameter $2        : ident                  "" | i (i == ident)
 471# - parameter $3        : eol in .gitattributs   "" (empty) | lf | crlf
 472# - parameter $4        : core.autocrlf          false | true | input
 473# - parameter $5        : core.eol               "" | lf | crlf | "native"
 474# - parameter $6        : reference for a file with only LF in the repo
 475# - parameter $7        : reference for a file with only CRLF in the repo
 476# - parameter $8        : reference for a file with mixed LF and CRLF in the repo
 477# - parameter $9        : reference for a file with LF and CR in the repo
 478# - parameter $10 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
 479
 480if test_have_prereq NATIVE_CRLF
 481then
 482MIX_CRLF_LF=CRLF
 483MIX_LF_CR=CRLF_mix_CR
 484NL=CRLF
 485LFNUL=CRLF_nul
 486else
 487MIX_CRLF_LF=CRLF_mix_LF
 488MIX_LF_CR=LF_mix_CR
 489NL=LF
 490LFNUL=LF_nul
 491fi
 492export CRLF_MIX_LF_CR MIX NL
 493
 494# Same handling with and without ident
 495for id in "" ident
 496do
 497        for ceol in lf crlf native
 498        do
 499                for crlf in true false input
 500                do
 501                        # -text overrides core.autocrlf and core.eol
 502                        # text and eol=crlf or eol=lf override core.autocrlf and core.eol
 503                        checkout_files -text "$id" ""     "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 504                        checkout_files -text "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 505                        checkout_files -text "$id" "crlf" "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 506                        # text
 507                        checkout_files text  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 508                        checkout_files text  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
 509                        # currently the same as text, eol=XXX
 510                        checkout_files auto  "$id" "lf"   "$crlf" "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 511                        checkout_files auto  "$id" "crlf" "$crlf" "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 512                done
 513
 514                # core.autocrlf false, different core.eol
 515                checkout_files   ""    "$id" ""     false   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 516                # core.autocrlf true
 517                checkout_files   ""    "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 518                # text: core.autocrlf = true overrides core.eol
 519                checkout_files   auto  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 520                checkout_files   text  "$id" ""     true    "$ceol"  CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
 521                # text: core.autocrlf = input overrides core.eol
 522                checkout_files   text  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 523                checkout_files   auto  "$id" ""     input   "$ceol"  LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 524                # text=auto + eol=XXX
 525        done
 526        # text: core.autocrlf=false uses core.eol
 527        checkout_files     text  "$id" ""     false   crlf     CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
 528        checkout_files     text  "$id" ""     false   lf       LF    CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 529        # text: core.autocrlf=false and core.eol unset(or native) uses native eol
 530        checkout_files     text  "$id" ""     false   ""       $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
 531        checkout_files     text  "$id" ""     false   native   $NL   CRLF  $MIX_CRLF_LF $MIX_LF_CR   $LFNUL
 532        # auto: core.autocrlf=false and core.eol unset(or native) uses native eol
 533        checkout_files     auto  "$id" ""     false   ""       $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 534        checkout_files     auto  "$id" ""     false   native   $NL   CRLF  CRLF_mix_LF  LF_mix_CR    LF_nul
 535done
 536
 537# Should be the last test case: remove some files from the worktree
 538test_expect_success 'ls-files --eol -d -z' '
 539        rm crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
 540        cat >expect <<-\EOF &&
 541        i/crlf w/ crlf_false_attr__CRLF.txt
 542        i/lf w/ .gitattributes
 543        i/lf w/ crlf_false_attr__LF.txt
 544        i/mixed w/ crlf_false_attr__CRLF_mix_LF.txt
 545        EOF
 546        git ls-files --eol -d |
 547        sed -e "s!attr/[^       ]*!!g" -e "s/   / /g" -e "s/  */ /g" |
 548        sort >actual &&
 549        test_cmp expect actual
 550'
 551
 552test_done