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