1#!/bin/sh
   2test_description='CRLF conversion'
   4. ./test-lib.sh
   6has_cr() {
   8        tr '\015' Q <"$1" | grep Q >/dev/null
   9}
  10test_expect_success setup '
  12        git config core.autocrlf false &&
  14        for w in Hello world how are you; do echo $w; done >one &&
  16        mkdir dir &&
  17        for w in I am very very fine thank you; do echo $w; done >dir/two &&
  18        for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&
  19        git add . &&
  20        git commit -m initial &&
  22        one=`git rev-parse HEAD:one` &&
  24        dir=`git rev-parse HEAD:dir` &&
  25        two=`git rev-parse HEAD:dir/two` &&
  26        three=`git rev-parse HEAD:three` &&
  27        for w in Some extra lines here; do echo $w; done >>one &&
  29        git diff >patch.file &&
  30        patched=`git hash-object --stdin <one` &&
  31        git read-tree --reset -u HEAD &&
  32        echo happy.
  34'
  35test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
  37        git config core.autocrlf input &&
  39        git config core.safecrlf true &&
  40        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
  42        test_must_fail git add allcrlf
  43'
  44test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
  46        git config core.autocrlf input &&
  48        git config core.safecrlf true &&
  49        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  51        test_must_fail git add mixed
  52'
  53test_expect_success 'safecrlf: autocrlf=true, all LF' '
  55        git config core.autocrlf true &&
  57        git config core.safecrlf true &&
  58        for w in I am all LF; do echo $w; done >alllf &&
  60        test_must_fail git add alllf
  61'
  62test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
  64        git config core.autocrlf true &&
  66        git config core.safecrlf true &&
  67        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  69        test_must_fail git add mixed
  70'
  71test_expect_success 'safecrlf: print warning only once' '
  73        git config core.autocrlf input &&
  75        git config core.safecrlf warn &&
  76        for w in I am all LF; do echo $w; done >doublewarn &&
  78        git add doublewarn &&
  79        git commit -m "nowarn" &&
  80        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
  81        test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1
  82'
  83test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
  85        git config core.autocrlf false &&
  86        git config core.safecrlf false &&
  87        git reset --hard HEAD^
  88'
  89test_expect_success 'update with autocrlf=input' '
  91        rm -f tmp one dir/two three &&
  93        git read-tree --reset -u HEAD &&
  94        git config core.autocrlf input &&
  95        for f in one dir/two
  97        do
  98                append_cr <$f >tmp && mv -f tmp $f &&
  99                git update-index -- $f || {
 100                        echo Oops
 101                        false
 102                        break
 103                }
 104        done &&
 105        differs=`git diff-index --cached HEAD` &&
 107        test -z "$differs" || {
 108                echo Oops "$differs"
 109                false
 110        }
 111'
 113test_expect_success 'update with autocrlf=true' '
 115        rm -f tmp one dir/two three &&
 117        git read-tree --reset -u HEAD &&
 118        git config core.autocrlf true &&
 119        for f in one dir/two
 121        do
 122                append_cr <$f >tmp && mv -f tmp $f &&
 123                git update-index -- $f || {
 124                        echo "Oops $f"
 125                        false
 126                        break
 127                }
 128        done &&
 129        differs=`git diff-index --cached HEAD` &&
 131        test -z "$differs" || {
 132                echo Oops "$differs"
 133                false
 134        }
 135'
 137test_expect_success 'checkout with autocrlf=true' '
 139        rm -f tmp one dir/two three &&
 141        git config core.autocrlf true &&
 142        git read-tree --reset -u HEAD &&
 143        for f in one dir/two
 145        do
 146                remove_cr <"$f" >tmp && mv -f tmp $f &&
 147                git update-index -- $f || {
 148                        echo "Eh? $f"
 149                        false
 150                        break
 151                }
 152        done &&
 153        test "$one" = `git hash-object --stdin <one` &&
 154        test "$two" = `git hash-object --stdin <dir/two` &&
 155        differs=`git diff-index --cached HEAD` &&
 156        test -z "$differs" || {
 157                echo Oops "$differs"
 158                false
 159        }
 160'
 161test_expect_success 'checkout with autocrlf=input' '
 163        rm -f tmp one dir/two three &&
 165        git config core.autocrlf input &&
 166        git read-tree --reset -u HEAD &&
 167        for f in one dir/two
 169        do
 170                if has_cr "$f"
 171                then
 172                        echo "Eh? $f"
 173                        false
 174                        break
 175                else
 176                        git update-index -- $f
 177                fi
 178        done &&
 179        test "$one" = `git hash-object --stdin <one` &&
 180        test "$two" = `git hash-object --stdin <dir/two` &&
 181        differs=`git diff-index --cached HEAD` &&
 182        test -z "$differs" || {
 183                echo Oops "$differs"
 184                false
 185        }
 186'
 187test_expect_success 'apply patch (autocrlf=input)' '
 189        rm -f tmp one dir/two three &&
 191        git config core.autocrlf input &&
 192        git read-tree --reset -u HEAD &&
 193        git apply patch.file &&
 195        test "$patched" = "`git hash-object --stdin <one`" || {
 196                echo "Eh?  apply without index"
 197                false
 198        }
 199'
 200test_expect_success 'apply patch --cached (autocrlf=input)' '
 202        rm -f tmp one dir/two three &&
 204        git config core.autocrlf input &&
 205        git read-tree --reset -u HEAD &&
 206        git apply --cached patch.file &&
 208        test "$patched" = `git rev-parse :one` || {
 209                echo "Eh?  apply with --cached"
 210                false
 211        }
 212'
 213test_expect_success 'apply patch --index (autocrlf=input)' '
 215        rm -f tmp one dir/two three &&
 217        git config core.autocrlf input &&
 218        git read-tree --reset -u HEAD &&
 219        git apply --index patch.file &&
 221        test "$patched" = `git rev-parse :one` &&
 222        test "$patched" = `git hash-object --stdin <one` || {
 223                echo "Eh?  apply with --index"
 224                false
 225        }
 226'
 227test_expect_success 'apply patch (autocrlf=true)' '
 229        rm -f tmp one dir/two three &&
 231        git config core.autocrlf true &&
 232        git read-tree --reset -u HEAD &&
 233        git apply patch.file &&
 235        test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
 236                echo "Eh?  apply without index"
 237                false
 238        }
 239'
 240test_expect_success 'apply patch --cached (autocrlf=true)' '
 242        rm -f tmp one dir/two three &&
 244        git config core.autocrlf true &&
 245        git read-tree --reset -u HEAD &&
 246        git apply --cached patch.file &&
 248        test "$patched" = `git rev-parse :one` || {
 249                echo "Eh?  apply without index"
 250                false
 251        }
 252'
 253test_expect_success 'apply patch --index (autocrlf=true)' '
 255        rm -f tmp one dir/two three &&
 257        git config core.autocrlf true &&
 258        git read-tree --reset -u HEAD &&
 259        git apply --index patch.file &&
 261        test "$patched" = `git rev-parse :one` &&
 262        test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
 263                echo "Eh?  apply with --index"
 264                false
 265        }
 266'
 267test_expect_success '.gitattributes says two is binary' '
 269        rm -f tmp one dir/two three &&
 271        echo "two -crlf" >.gitattributes &&
 272        git config core.autocrlf true &&
 273        git read-tree --reset -u HEAD &&
 274        if has_cr dir/two
 276        then
 277                echo "Huh?"
 278                false
 279        else
 280                : happy
 281        fi &&
 282        if has_cr one
 284        then
 285                : happy
 286        else
 287                echo "Huh?"
 288                false
 289        fi &&
 290        if has_cr three
 292        then
 293                echo "Huh?"
 294                false
 295        else
 296                : happy
 297        fi
 298'
 299test_expect_success '.gitattributes says two is input' '
 301        rm -f tmp one dir/two three &&
 303        echo "two crlf=input" >.gitattributes &&
 304        git read-tree --reset -u HEAD &&
 305        if has_cr dir/two
 307        then
 308                echo "Huh?"
 309                false
 310        else
 311                : happy
 312        fi
 313'
 314test_expect_success '.gitattributes says two and three are text' '
 316        rm -f tmp one dir/two three &&
 318        echo "t* crlf" >.gitattributes &&
 319        git read-tree --reset -u HEAD &&
 320        if has_cr dir/two
 322        then
 323                : happy
 324        else
 325                echo "Huh?"
 326                false
 327        fi &&
 328        if has_cr three
 330        then
 331                : happy
 332        else
 333                echo "Huh?"
 334                false
 335        fi
 336'
 337test_expect_success 'in-tree .gitattributes (1)' '
 339        echo "one -crlf" >>.gitattributes &&
 341        git add .gitattributes &&
 342        git commit -m "Add .gitattributes" &&
 343        rm -rf tmp one dir .gitattributes patch.file three &&
 345        git read-tree --reset -u HEAD &&
 346        if has_cr one
 348        then
 349                echo "Eh? one should not have CRLF"
 350                false
 351        else
 352                : happy
 353        fi &&
 354        has_cr three || {
 355                echo "Eh? three should still have CRLF"
 356                false
 357        }
 358'
 359test_expect_success 'in-tree .gitattributes (2)' '
 361        rm -rf tmp one dir .gitattributes patch.file three &&
 363        git read-tree --reset HEAD &&
 364        git checkout-index -f -q -u -a &&
 365        if has_cr one
 367        then
 368                echo "Eh? one should not have CRLF"
 369                false
 370        else
 371                : happy
 372        fi &&
 373        has_cr three || {
 374                echo "Eh? three should still have CRLF"
 375                false
 376        }
 377'
 378test_expect_success 'in-tree .gitattributes (3)' '
 380        rm -rf tmp one dir .gitattributes patch.file three &&
 382        git read-tree --reset HEAD &&
 383        git checkout-index -u .gitattributes &&
 384        git checkout-index -u one dir/two three &&
 385        if has_cr one
 387        then
 388                echo "Eh? one should not have CRLF"
 389                false
 390        else
 391                : happy
 392        fi &&
 393        has_cr three || {
 394                echo "Eh? three should still have CRLF"
 395                false
 396        }
 397'
 398test_expect_success 'in-tree .gitattributes (4)' '
 400        rm -rf tmp one dir .gitattributes patch.file three &&
 402        git read-tree --reset HEAD &&
 403        git checkout-index -u one dir/two three &&
 404        git checkout-index -u .gitattributes &&
 405        if has_cr one
 407        then
 408                echo "Eh? one should not have CRLF"
 409                false
 410        else
 411                : happy
 412        fi &&
 413        has_cr three || {
 414                echo "Eh? three should still have CRLF"
 415                false
 416        }
 417'
 418test_expect_success 'checkout with existing .gitattributes' '
 420        git config core.autocrlf true &&
 422        git config --unset core.safecrlf &&
 423        echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
 424        git add .gitattributes &&
 425        git commit -m initial &&
 426        echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
 427        echo "contents" > .file &&
 428        git add .gitattributes .file &&
 429        git commit -m second &&
 430        git checkout master~1 &&
 432        git checkout master &&
 433        test "$(git diff-files --raw)" = ""
 434'
 436test_expect_success 'checkout when deleting .gitattributes' '
 438        git rm .gitattributes &&
 440        echo "contentsQ" | q_to_cr > .file2 &&
 441        git add .file2 &&
 442        git commit -m third &&
 443        git checkout master~1 &&
 445        git checkout master &&
 446        has_cr .file2
 447'
 449test_expect_success 'invalid .gitattributes (must not crash)' '
 451        echo "three +crlf" >>.gitattributes &&
 453        git diff
 454'
 456# Some more tests here to add new autocrlf functionality.
 457# We want to have a known state here, so start a bit from scratch
 458test_expect_success 'setting up for new autocrlf tests' '
 460        git config core.autocrlf false &&
 461        git config core.safecrlf false &&
 462        rm -rf .????* * &&
 463        for w in I am all LF; do echo $w; done >alllf &&
 464        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
 465        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
 466        git add -A . &&
 467        git commit -m "alllf, allcrlf and mixed only" &&
 468        git tag -a -m "message" autocrlf-checkpoint
 469'
 470test_expect_success 'report no change after setting autocrlf' '
 472        git config core.autocrlf true &&
 473        touch * &&
 474        git diff --exit-code
 475'
 476test_expect_success 'files are clean after checkout' '
 478        rm * &&
 479        git checkout -f &&
 480        git diff --exit-code
 481'
 482cr_to_Q_no_NL () {
 484    tr '\015' Q | tr -d '\012'
 485}
 486test_expect_success 'LF only file gets CRLF with autocrlf' '
 488        test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
 489'
 490test_expect_success 'Mixed file is still mixed with autocrlf' '
 492        test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
 493'
 494test_expect_success 'CRLF only file has CRLF with autocrlf' '
 496        test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
 497'
 498test_expect_success 'New CRLF file gets LF in repo' '
 500        tr -d "\015" < alllf | append_cr > alllf2 &&
 501        git add alllf2 &&
 502        git commit -m "alllf2 added" &&
 503        git config core.autocrlf false &&
 504        rm * &&
 505        git checkout -f &&
 506        test_cmp alllf alllf2
 507'
 508test_done