t / t0027-auto-crlf.shon commit Merge branch 'js/libify-require-clean-work-tree' (2bee56b)
   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>"${pfx}_$f.err"
 123        done
 124
 125        test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
 126                check_warning "$lfwarn" ${pfx}_LF.err
 127        '
 128        test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF" '
 129                check_warning "$crlfwarn" ${pfx}_CRLF.err
 130        '
 131
 132        test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_mix_LF" '
 133                check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
 134        '
 135
 136        test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf LF_mix_cr" '
 137                check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
 138        '
 139
 140        test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_nul" '
 141                check_warning "$crlfnul" ${pfx}_CRLF_nul.err
 142        '
 143}
 144
 145stats_ascii () {
 146        case "$1" in
 147        LF)
 148                echo lf
 149                ;;
 150        CRLF)
 151                echo crlf
 152                ;;
 153        CRLF_mix_LF)
 154                echo mixed
 155                ;;
 156        LF_mix_CR|CRLF_nul|LF_nul|CRLF_mix_CR)
 157                echo "-text"
 158                ;;
 159        *)
 160                echo error_invalid $1
 161                ;;
 162        esac
 163
 164}
 165
 166
 167# contruct the attr/ returned by git ls-files --eol
 168# Take none (=empty), one or two args
 169# convert.c: eol=XX overrides text=auto
 170attr_ascii () {
 171        case $1,$2 in
 172        -text,*)   echo "-text" ;;
 173        text,)     echo "text" ;;
 174        text,lf)   echo "text eol=lf" ;;
 175        text,crlf) echo "text eol=crlf" ;;
 176        auto,)     echo "text=auto" ;;
 177        auto,lf)   echo "text=auto eol=lf" ;;
 178        auto,crlf) echo "text=auto eol=crlf" ;;
 179        lf,)       echo "text eol=lf" ;;
 180        crlf,)     echo "text eol=crlf" ;;
 181        ,) echo "" ;;
 182        *) echo invalid_attr "$1,$2" ;;
 183        esac
 184}
 185
 186check_files_in_repo () {
 187        crlf=$1
 188        attr=$2
 189        lfname=$3
 190        crlfname=$4
 191        lfmixcrlf=$5
 192        lfmixcr=$6
 193        crlfnul=$7
 194        pfx=crlf_${crlf}_attr_${attr}_ &&
 195        compare_files $lfname ${pfx}LF.txt &&
 196        compare_files $crlfname ${pfx}CRLF.txt &&
 197        compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt &&
 198        compare_files $lfmixcr ${pfx}LF_mix_CR.txt &&
 199        compare_files $crlfnul ${pfx}CRLF_nul.txt
 200}
 201
 202check_in_repo_NNO () {
 203        attr=$1 ; shift
 204        aeol=$1 ; shift
 205        crlf=$1 ; shift
 206        lfname=$1 ; shift
 207        crlfname=$1 ; shift
 208        lfmixcrlf=$1 ; shift
 209        lfmixcr=$1 ; shift
 210        crlfnul=$1 ; shift
 211        pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
 212        test_expect_success "compare_files $lfname ${pfx}_LF.txt" '
 213                compare_files $lfname ${pfx}_LF.txt
 214        '
 215        test_expect_success "compare_files $crlfname ${pfx}_CRLF.txt" '
 216                compare_files $crlfname ${pfx}_CRLF.txt
 217        '
 218        test_expect_success "compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt" '
 219                compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt
 220        '
 221        test_expect_success "compare_files $lfmixcr ${pfx}_LF_mix_CR.txt" '
 222                compare_files $lfmixcr ${pfx}_LF_mix_CR.txt
 223        '
 224        test_expect_success "compare_files $crlfnul ${pfx}_CRLF_nul.txt" '
 225                compare_files $crlfnul ${pfx}_CRLF_nul.txt
 226        '
 227}
 228
 229checkout_files () {
 230        attr=$1 ; shift
 231        ident=$1; shift
 232        aeol=$1 ; shift
 233        crlf=$1 ; shift
 234        ceol=$1 ; shift
 235        lfname=$1 ; shift
 236        crlfname=$1 ; shift
 237        lfmixcrlf=$1 ; shift
 238        lfmixcr=$1 ; shift
 239        crlfnul=$1 ; shift
 240        create_gitattributes "$attr" $ident $aeol &&
 241        git config core.autocrlf $crlf &&
 242        pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 243        for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 244        do
 245                rm crlf_false_attr__$f.txt &&
 246                if test -z "$ceol"; then
 247                        git checkout crlf_false_attr__$f.txt
 248                else
 249                        git -c core.eol=$ceol checkout crlf_false_attr__$f.txt
 250                fi
 251        done
 252
 253        test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
 254                test_when_finished "rm expect actual" &&
 255                sort <<-EOF >expect &&
 256                i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt
 257                i/mixed w/$(stats_ascii $lfmixcrlf) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_mix_LF.txt
 258                i/lf w/$(stats_ascii $lfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF.txt
 259                i/-text w/$(stats_ascii $lfmixcr) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_mix_CR.txt
 260                i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_nul.txt
 261                i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_nul.txt
 262                EOF
 263                git ls-files --eol crlf_false_attr__* |
 264                sed -e "s/      / /g" -e "s/  */ /g" |
 265                sort >actual &&
 266                test_cmp expect actual
 267        '
 268        test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF" "
 269                compare_ws_file $pfx $lfname    crlf_false_attr__LF.txt
 270        "
 271        test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" "
 272                compare_ws_file $pfx $crlfname  crlf_false_attr__CRLF.txt
 273        "
 274        test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" "
 275                compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt
 276        "
 277        test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" "
 278                compare_ws_file $pfx $lfmixcr   crlf_false_attr__LF_mix_CR.txt
 279        "
 280        test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" "
 281                compare_ws_file $pfx $crlfnul   crlf_false_attr__LF_nul.txt
 282        "
 283}
 284
 285# Test control characters
 286# NUL SOH CR EOF==^Z
 287test_expect_success 'ls-files --eol -o Text/Binary' '
 288        test_when_finished "rm expect actual TeBi_*" &&
 289        STRT=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &&
 290        STR=$STRT$STRT$STRT$STRT &&
 291        printf "${STR}BBB\001" >TeBi_127_S &&
 292        printf "${STR}BBBB\001">TeBi_128_S &&
 293        printf "${STR}BBB\032" >TeBi_127_E &&
 294        printf "\032${STR}BBB" >TeBi_E_127 &&
 295        printf "${STR}BBBB\000">TeBi_128_N &&
 296        printf "${STR}BBB\012">TeBi_128_L &&
 297        printf "${STR}BBB\015">TeBi_127_C &&
 298        printf "${STR}BB\015\012" >TeBi_126_CL &&
 299        printf "${STR}BB\015\012\015" >TeBi_126_CLC &&
 300        sort <<-\EOF >expect &&
 301        i/ w/-text TeBi_127_S
 302        i/ w/none TeBi_128_S
 303        i/ w/none TeBi_127_E
 304        i/ w/-text TeBi_E_127
 305        i/ w/-text TeBi_128_N
 306        i/ w/lf TeBi_128_L
 307        i/ w/-text TeBi_127_C
 308        i/ w/crlf TeBi_126_CL
 309        i/ w/-text TeBi_126_CLC
 310        EOF
 311        git ls-files --eol -o |
 312        sed -n -e "/TeBi_/{s!attr/[     ]*!!g
 313        s!      ! !g
 314        s!  *! !g
 315        p
 316        }" | sort >actual &&
 317        test_cmp expect actual
 318'
 319
 320test_expect_success 'setup master' '
 321        echo >.gitattributes &&
 322        git checkout -b master &&
 323        git add .gitattributes &&
 324        git commit -m "add .gitattributes" "" &&
 325        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\nLINETHREE"     >LF &&
 326        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\r\nLINETHREE" >CRLF &&
 327        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\r\nLINETWO\nLINETHREE"   >CRLF_mix_LF &&
 328        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\rLINETHREE"     >LF_mix_CR &&
 329        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\rLINETHREE"   >CRLF_mix_CR &&
 330        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONEQ\r\nLINETWO\r\nLINETHREE" | q_to_nul >CRLF_nul &&
 331        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONEQ\nLINETWO\nLINETHREE" | q_to_nul >LF_nul &&
 332        create_NNO_files CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF &&
 333        git -c core.autocrlf=false add NNO_*.txt &&
 334        git commit -m "mixed line endings" &&
 335        test_tick
 336'
 337
 338
 339
 340warn_LF_CRLF="LF will be replaced by CRLF"
 341warn_CRLF_LF="CRLF will be replaced by LF"
 342
 343# WILC stands for "Warn if (this OS) converts LF into CRLF".
 344# WICL: Warn if CRLF becomes LF
 345# WAMIX: Mixed line endings: either CRLF->LF or LF->CRLF
 346if test_have_prereq NATIVE_CRLF
 347then
 348        WILC=LF_CRLF
 349        WICL=
 350        WAMIX=LF_CRLF
 351else
 352        WILC=
 353        WICL=CRLF_LF
 354        WAMIX=CRLF_LF
 355fi
 356
 357#                         attr   LF        CRLF      CRLFmixLF LFmixCR   CRLFNUL
 358test_expect_success 'commit files empty attr' '
 359        commit_check_warn false ""     ""        ""        ""        ""        "" &&
 360        commit_check_warn true  ""     "LF_CRLF" ""        "LF_CRLF" ""        "" &&
 361        commit_check_warn input ""     ""        "CRLF_LF" "CRLF_LF" ""        ""
 362'
 363
 364test_expect_success 'commit files attr=auto' '
 365        commit_check_warn false "auto" "$WILC"   "$WICL"   "$WAMIX"  ""        "" &&
 366        commit_check_warn true  "auto" "LF_CRLF" ""        "LF_CRLF" ""        "" &&
 367        commit_check_warn input "auto" ""        "CRLF_LF" "CRLF_LF" ""        ""
 368'
 369
 370test_expect_success 'commit files attr=text' '
 371        commit_check_warn false "text" "$WILC"   "$WICL"   "$WAMIX"  "$WILC"   "$WICL"   &&
 372        commit_check_warn true  "text" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""        &&
 373        commit_check_warn input "text" ""        "CRLF_LF" "CRLF_LF" ""        "CRLF_LF"
 374'
 375
 376test_expect_success 'commit files attr=-text' '
 377        commit_check_warn false "-text" ""       ""        ""        ""        "" &&
 378        commit_check_warn true  "-text" ""       ""        ""        ""        "" &&
 379        commit_check_warn input "-text" ""       ""        ""        ""        ""
 380'
 381
 382test_expect_success 'commit files attr=lf' '
 383        commit_check_warn false "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
 384        commit_check_warn true  "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF" &&
 385        commit_check_warn input "lf"    ""       "CRLF_LF" "CRLF_LF"  ""       "CRLF_LF"
 386'
 387
 388test_expect_success 'commit files attr=crlf' '
 389        commit_check_warn false "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
 390        commit_check_warn true  "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" "" &&
 391        commit_check_warn input "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""
 392'
 393
 394#                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
 395commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
 396commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""
 397commit_chk_wrnNNO ""      ""      input   ""        ""        ""          ""          ""
 398
 399commit_chk_wrnNNO "auto"  ""      false   "$WILC"   ""        ""          ""          ""
 400commit_chk_wrnNNO "auto"  ""      true    LF_CRLF   ""        ""          ""          ""
 401commit_chk_wrnNNO "auto"  ""      input   ""        ""        ""          ""          ""
 402for crlf in true false input
 403do
 404        commit_chk_wrnNNO -text ""      $crlf   ""        ""        ""          ""          ""
 405        commit_chk_wrnNNO -text lf      $crlf   ""        ""        ""          ""          ""
 406        commit_chk_wrnNNO -text crlf    $crlf   ""        ""        ""          ""          ""
 407        commit_chk_wrnNNO ""    lf      $crlf   ""       CRLF_LF    CRLF_LF      ""         CRLF_LF
 408        commit_chk_wrnNNO ""    crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 409        commit_chk_wrnNNO auto  lf      $crlf   ""        ""        ""          ""          ""
 410        commit_chk_wrnNNO auto  crlf    $crlf   LF_CRLF   ""        ""          ""          ""
 411        commit_chk_wrnNNO text  lf      $crlf   ""       CRLF_LF    CRLF_LF     ""          CRLF_LF
 412        commit_chk_wrnNNO text  crlf    $crlf   LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 413done
 414
 415commit_chk_wrnNNO "text"  ""      false   "$WILC"   "$WICL"   "$WAMIX"    "$WILC"     "$WICL"
 416commit_chk_wrnNNO "text"  ""      true    LF_CRLF   ""        LF_CRLF     LF_CRLF     ""
 417commit_chk_wrnNNO "text"  ""      input   ""        CRLF_LF   CRLF_LF     ""          CRLF_LF
 418
 419test_expect_success 'commit NNO and cleanup' '
 420        git commit -m "commit files on top of NNO" &&
 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