t / t0020-crlf.shon commit xread/xwrite: clip MAX_IO_SIZE to SSIZE_MAX (a983e6a)
   1#!/bin/sh
   2
   3test_description='CRLF conversion'
   4
   5. ./test-lib.sh
   6
   7has_cr() {
   8        tr '\015' Q <"$1" | grep Q >/dev/null
   9}
  10
  11test_expect_success setup '
  12
  13        git config core.autocrlf false &&
  14
  15        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
  21        git commit -m initial &&
  22
  23        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
  28        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
  33        echo happy.
  34'
  35
  36test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
  37
  38        git config core.autocrlf input &&
  39        git config core.safecrlf true &&
  40
  41        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
  42        test_must_fail git add allcrlf
  43'
  44
  45test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
  46
  47        git config core.autocrlf input &&
  48        git config core.safecrlf true &&
  49
  50        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'
  53
  54test_expect_success 'safecrlf: autocrlf=true, all LF' '
  55
  56        git config core.autocrlf true &&
  57        git config core.safecrlf true &&
  58
  59        for w in I am all LF; do echo $w; done >alllf &&
  60        test_must_fail git add alllf
  61'
  62
  63test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
  64
  65        git config core.autocrlf true &&
  66        git config core.safecrlf true &&
  67
  68        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'
  71
  72test_expect_success 'safecrlf: print warning only once' '
  73
  74        git config core.autocrlf input &&
  75        git config core.safecrlf warn &&
  76
  77        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'
  83
  84
  85test_expect_success 'safecrlf: git diff demotes safecrlf=true to warn' '
  86        git config core.autocrlf input &&
  87        git config core.safecrlf true &&
  88        git diff HEAD
  89'
  90
  91
  92test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
  93        git config core.autocrlf false &&
  94        git config core.safecrlf false &&
  95        git reset --hard HEAD^
  96'
  97
  98test_expect_success 'update with autocrlf=input' '
  99
 100        rm -f tmp one dir/two three &&
 101        git read-tree --reset -u HEAD &&
 102        git config core.autocrlf input &&
 103
 104        for f in one dir/two
 105        do
 106                append_cr <$f >tmp && mv -f tmp $f &&
 107                git update-index -- $f || {
 108                        echo Oops
 109                        false
 110                        break
 111                }
 112        done &&
 113
 114        differs=`git diff-index --cached HEAD` &&
 115        test -z "$differs" || {
 116                echo Oops "$differs"
 117                false
 118        }
 119
 120'
 121
 122test_expect_success 'update with autocrlf=true' '
 123
 124        rm -f tmp one dir/two three &&
 125        git read-tree --reset -u HEAD &&
 126        git config core.autocrlf true &&
 127
 128        for f in one dir/two
 129        do
 130                append_cr <$f >tmp && mv -f tmp $f &&
 131                git update-index -- $f || {
 132                        echo "Oops $f"
 133                        false
 134                        break
 135                }
 136        done &&
 137
 138        differs=`git diff-index --cached HEAD` &&
 139        test -z "$differs" || {
 140                echo Oops "$differs"
 141                false
 142        }
 143
 144'
 145
 146test_expect_success 'checkout with autocrlf=true' '
 147
 148        rm -f tmp one dir/two three &&
 149        git config core.autocrlf true &&
 150        git read-tree --reset -u HEAD &&
 151
 152        for f in one dir/two
 153        do
 154                remove_cr <"$f" >tmp && mv -f tmp $f &&
 155                git update-index -- $f || {
 156                        echo "Eh? $f"
 157                        false
 158                        break
 159                }
 160        done &&
 161        test "$one" = `git hash-object --stdin <one` &&
 162        test "$two" = `git hash-object --stdin <dir/two` &&
 163        differs=`git diff-index --cached HEAD` &&
 164        test -z "$differs" || {
 165                echo Oops "$differs"
 166                false
 167        }
 168'
 169
 170test_expect_success 'checkout with autocrlf=input' '
 171
 172        rm -f tmp one dir/two three &&
 173        git config core.autocrlf input &&
 174        git read-tree --reset -u HEAD &&
 175
 176        for f in one dir/two
 177        do
 178                if has_cr "$f"
 179                then
 180                        echo "Eh? $f"
 181                        false
 182                        break
 183                else
 184                        git update-index -- $f
 185                fi
 186        done &&
 187        test "$one" = `git hash-object --stdin <one` &&
 188        test "$two" = `git hash-object --stdin <dir/two` &&
 189        differs=`git diff-index --cached HEAD` &&
 190        test -z "$differs" || {
 191                echo Oops "$differs"
 192                false
 193        }
 194'
 195
 196test_expect_success 'apply patch (autocrlf=input)' '
 197
 198        rm -f tmp one dir/two three &&
 199        git config core.autocrlf input &&
 200        git read-tree --reset -u HEAD &&
 201
 202        git apply patch.file &&
 203        test "$patched" = "`git hash-object --stdin <one`" || {
 204                echo "Eh?  apply without index"
 205                false
 206        }
 207'
 208
 209test_expect_success 'apply patch --cached (autocrlf=input)' '
 210
 211        rm -f tmp one dir/two three &&
 212        git config core.autocrlf input &&
 213        git read-tree --reset -u HEAD &&
 214
 215        git apply --cached patch.file &&
 216        test "$patched" = `git rev-parse :one` || {
 217                echo "Eh?  apply with --cached"
 218                false
 219        }
 220'
 221
 222test_expect_success 'apply patch --index (autocrlf=input)' '
 223
 224        rm -f tmp one dir/two three &&
 225        git config core.autocrlf input &&
 226        git read-tree --reset -u HEAD &&
 227
 228        git apply --index patch.file &&
 229        test "$patched" = `git rev-parse :one` &&
 230        test "$patched" = `git hash-object --stdin <one` || {
 231                echo "Eh?  apply with --index"
 232                false
 233        }
 234'
 235
 236test_expect_success 'apply patch (autocrlf=true)' '
 237
 238        rm -f tmp one dir/two three &&
 239        git config core.autocrlf true &&
 240        git read-tree --reset -u HEAD &&
 241
 242        git apply patch.file &&
 243        test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
 244                echo "Eh?  apply without index"
 245                false
 246        }
 247'
 248
 249test_expect_success 'apply patch --cached (autocrlf=true)' '
 250
 251        rm -f tmp one dir/two three &&
 252        git config core.autocrlf true &&
 253        git read-tree --reset -u HEAD &&
 254
 255        git apply --cached patch.file &&
 256        test "$patched" = `git rev-parse :one` || {
 257                echo "Eh?  apply without index"
 258                false
 259        }
 260'
 261
 262test_expect_success 'apply patch --index (autocrlf=true)' '
 263
 264        rm -f tmp one dir/two three &&
 265        git config core.autocrlf true &&
 266        git read-tree --reset -u HEAD &&
 267
 268        git apply --index patch.file &&
 269        test "$patched" = `git rev-parse :one` &&
 270        test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
 271                echo "Eh?  apply with --index"
 272                false
 273        }
 274'
 275
 276test_expect_success '.gitattributes says two is binary' '
 277
 278        rm -f tmp one dir/two three &&
 279        echo "two -crlf" >.gitattributes &&
 280        git config core.autocrlf true &&
 281        git read-tree --reset -u HEAD &&
 282
 283        if has_cr dir/two
 284        then
 285                echo "Huh?"
 286                false
 287        else
 288                : happy
 289        fi &&
 290
 291        if has_cr one
 292        then
 293                : happy
 294        else
 295                echo "Huh?"
 296                false
 297        fi &&
 298
 299        if has_cr three
 300        then
 301                echo "Huh?"
 302                false
 303        else
 304                : happy
 305        fi
 306'
 307
 308test_expect_success '.gitattributes says two is input' '
 309
 310        rm -f tmp one dir/two three &&
 311        echo "two crlf=input" >.gitattributes &&
 312        git read-tree --reset -u HEAD &&
 313
 314        if has_cr dir/two
 315        then
 316                echo "Huh?"
 317                false
 318        else
 319                : happy
 320        fi
 321'
 322
 323test_expect_success '.gitattributes says two and three are text' '
 324
 325        rm -f tmp one dir/two three &&
 326        echo "t* crlf" >.gitattributes &&
 327        git read-tree --reset -u HEAD &&
 328
 329        if has_cr dir/two
 330        then
 331                : happy
 332        else
 333                echo "Huh?"
 334                false
 335        fi &&
 336
 337        if has_cr three
 338        then
 339                : happy
 340        else
 341                echo "Huh?"
 342                false
 343        fi
 344'
 345
 346test_expect_success 'in-tree .gitattributes (1)' '
 347
 348        echo "one -crlf" >>.gitattributes &&
 349        git add .gitattributes &&
 350        git commit -m "Add .gitattributes" &&
 351
 352        rm -rf tmp one dir .gitattributes patch.file three &&
 353        git read-tree --reset -u HEAD &&
 354
 355        if has_cr one
 356        then
 357                echo "Eh? one should not have CRLF"
 358                false
 359        else
 360                : happy
 361        fi &&
 362        has_cr three || {
 363                echo "Eh? three should still have CRLF"
 364                false
 365        }
 366'
 367
 368test_expect_success 'in-tree .gitattributes (2)' '
 369
 370        rm -rf tmp one dir .gitattributes patch.file three &&
 371        git read-tree --reset HEAD &&
 372        git checkout-index -f -q -u -a &&
 373
 374        if has_cr one
 375        then
 376                echo "Eh? one should not have CRLF"
 377                false
 378        else
 379                : happy
 380        fi &&
 381        has_cr three || {
 382                echo "Eh? three should still have CRLF"
 383                false
 384        }
 385'
 386
 387test_expect_success 'in-tree .gitattributes (3)' '
 388
 389        rm -rf tmp one dir .gitattributes patch.file three &&
 390        git read-tree --reset HEAD &&
 391        git checkout-index -u .gitattributes &&
 392        git checkout-index -u one dir/two three &&
 393
 394        if has_cr one
 395        then
 396                echo "Eh? one should not have CRLF"
 397                false
 398        else
 399                : happy
 400        fi &&
 401        has_cr three || {
 402                echo "Eh? three should still have CRLF"
 403                false
 404        }
 405'
 406
 407test_expect_success 'in-tree .gitattributes (4)' '
 408
 409        rm -rf tmp one dir .gitattributes patch.file three &&
 410        git read-tree --reset HEAD &&
 411        git checkout-index -u one dir/two three &&
 412        git checkout-index -u .gitattributes &&
 413
 414        if has_cr one
 415        then
 416                echo "Eh? one should not have CRLF"
 417                false
 418        else
 419                : happy
 420        fi &&
 421        has_cr three || {
 422                echo "Eh? three should still have CRLF"
 423                false
 424        }
 425'
 426
 427test_expect_success 'checkout with existing .gitattributes' '
 428
 429        git config core.autocrlf true &&
 430        git config --unset core.safecrlf &&
 431        echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
 432        git add .gitattributes &&
 433        git commit -m initial &&
 434        echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
 435        echo "contents" > .file &&
 436        git add .gitattributes .file &&
 437        git commit -m second &&
 438
 439        git checkout master~1 &&
 440        git checkout master &&
 441        test "$(git diff-files --raw)" = ""
 442
 443'
 444
 445test_expect_success 'checkout when deleting .gitattributes' '
 446
 447        git rm .gitattributes &&
 448        echo "contentsQ" | q_to_cr > .file2 &&
 449        git add .file2 &&
 450        git commit -m third &&
 451
 452        git checkout master~1 &&
 453        git checkout master &&
 454        has_cr .file2
 455
 456'
 457
 458test_expect_success 'invalid .gitattributes (must not crash)' '
 459
 460        echo "three +crlf" >>.gitattributes &&
 461        git diff
 462
 463'
 464# Some more tests here to add new autocrlf functionality.
 465# We want to have a known state here, so start a bit from scratch
 466
 467test_expect_success 'setting up for new autocrlf tests' '
 468        git config core.autocrlf false &&
 469        git config core.safecrlf false &&
 470        rm -rf .????* * &&
 471        for w in I am all LF; do echo $w; done >alllf &&
 472        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
 473        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
 474        git add -A . &&
 475        git commit -m "alllf, allcrlf and mixed only" &&
 476        git tag -a -m "message" autocrlf-checkpoint
 477'
 478
 479test_expect_success 'report no change after setting autocrlf' '
 480        git config core.autocrlf true &&
 481        touch * &&
 482        git diff --exit-code
 483'
 484
 485test_expect_success 'files are clean after checkout' '
 486        rm * &&
 487        git checkout -f &&
 488        git diff --exit-code
 489'
 490
 491cr_to_Q_no_NL () {
 492    tr '\015' Q | tr -d '\012'
 493}
 494
 495test_expect_success 'LF only file gets CRLF with autocrlf' '
 496        test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
 497'
 498
 499test_expect_success 'Mixed file is still mixed with autocrlf' '
 500        test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
 501'
 502
 503test_expect_success 'CRLF only file has CRLF with autocrlf' '
 504        test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
 505'
 506
 507test_expect_success 'New CRLF file gets LF in repo' '
 508        tr -d "\015" < alllf | append_cr > alllf2 &&
 509        git add alllf2 &&
 510        git commit -m "alllf2 added" &&
 511        git config core.autocrlf false &&
 512        rm * &&
 513        git checkout -f &&
 514        test_cmp alllf alllf2
 515'
 516
 517test_done