t / t0020-crlf.shon commit Merge branch 'np/push-delta' into maint (4619136)
   1#!/bin/sh
   2
   3test_description='CRLF conversion'
   4
   5. ./test-lib.sh
   6
   7q_to_nul () {
   8        perl -pe 'y/Q/\000/'
   9}
  10
  11q_to_cr () {
  12        tr Q '\015'
  13}
  14
  15append_cr () {
  16        sed -e 's/$/Q/' | tr Q '\015'
  17}
  18
  19remove_cr () {
  20        tr '\015' Q <"$1" | grep Q >/dev/null &&
  21        tr '\015' Q <"$1" | sed -ne 's/Q$//p'
  22}
  23
  24test_expect_success setup '
  25
  26        git config core.autocrlf false &&
  27
  28        for w in Hello world how are you; do echo $w; done >one &&
  29        mkdir dir &&
  30        for w in I am very very fine thank you; do echo $w; done >dir/two &&
  31        for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&
  32        git add . &&
  33
  34        git commit -m initial &&
  35
  36        one=`git rev-parse HEAD:one` &&
  37        dir=`git rev-parse HEAD:dir` &&
  38        two=`git rev-parse HEAD:dir/two` &&
  39        three=`git rev-parse HEAD:three` &&
  40
  41        for w in Some extra lines here; do echo $w; done >>one &&
  42        git diff >patch.file &&
  43        patched=`git hash-object --stdin <one` &&
  44        git read-tree --reset -u HEAD &&
  45
  46        echo happy.
  47'
  48
  49test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
  50
  51        git config core.autocrlf input &&
  52        git config core.safecrlf true &&
  53
  54        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
  55        test_must_fail git add allcrlf
  56'
  57
  58test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
  59
  60        git config core.autocrlf input &&
  61        git config core.safecrlf true &&
  62
  63        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  64        test_must_fail git add mixed
  65'
  66
  67test_expect_success 'safecrlf: autocrlf=true, all LF' '
  68
  69        git config core.autocrlf true &&
  70        git config core.safecrlf true &&
  71
  72        for w in I am all LF; do echo $w; done >alllf &&
  73        test_must_fail git add alllf
  74'
  75
  76test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
  77
  78        git config core.autocrlf true &&
  79        git config core.safecrlf true &&
  80
  81        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  82        test_must_fail git add mixed
  83'
  84
  85test_expect_success 'safecrlf: print warning only once' '
  86
  87        git config core.autocrlf input &&
  88        git config core.safecrlf warn &&
  89
  90        for w in I am all LF; do echo $w; done >doublewarn &&
  91        git add doublewarn &&
  92        git commit -m "nowarn" &&
  93        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
  94        test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1
  95'
  96
  97test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
  98        git config core.autocrlf false &&
  99        git config core.safecrlf false &&
 100        git reset --hard HEAD^
 101'
 102
 103test_expect_success 'update with autocrlf=input' '
 104
 105        rm -f tmp one dir/two three &&
 106        git read-tree --reset -u HEAD &&
 107        git config core.autocrlf input &&
 108
 109        for f in one dir/two
 110        do
 111                append_cr <$f >tmp && mv -f tmp $f &&
 112                git update-index -- $f || {
 113                        echo Oops
 114                        false
 115                        break
 116                }
 117        done &&
 118
 119        differs=`git diff-index --cached HEAD` &&
 120        test -z "$differs" || {
 121                echo Oops "$differs"
 122                false
 123        }
 124
 125'
 126
 127test_expect_success 'update with autocrlf=true' '
 128
 129        rm -f tmp one dir/two three &&
 130        git read-tree --reset -u HEAD &&
 131        git config core.autocrlf true &&
 132
 133        for f in one dir/two
 134        do
 135                append_cr <$f >tmp && mv -f tmp $f &&
 136                git update-index -- $f || {
 137                        echo "Oops $f"
 138                        false
 139                        break
 140                }
 141        done &&
 142
 143        differs=`git diff-index --cached HEAD` &&
 144        test -z "$differs" || {
 145                echo Oops "$differs"
 146                false
 147        }
 148
 149'
 150
 151test_expect_success 'checkout with autocrlf=true' '
 152
 153        rm -f tmp one dir/two three &&
 154        git config core.autocrlf true &&
 155        git read-tree --reset -u HEAD &&
 156
 157        for f in one dir/two
 158        do
 159                remove_cr "$f" >tmp && mv -f tmp $f &&
 160                git update-index -- $f || {
 161                        echo "Eh? $f"
 162                        false
 163                        break
 164                }
 165        done &&
 166        test "$one" = `git hash-object --stdin <one` &&
 167        test "$two" = `git hash-object --stdin <dir/two` &&
 168        differs=`git diff-index --cached HEAD` &&
 169        test -z "$differs" || {
 170                echo Oops "$differs"
 171                false
 172        }
 173'
 174
 175test_expect_success 'checkout with autocrlf=input' '
 176
 177        rm -f tmp one dir/two three &&
 178        git config core.autocrlf input &&
 179        git read-tree --reset -u HEAD &&
 180
 181        for f in one dir/two
 182        do
 183                if remove_cr "$f" >/dev/null
 184                then
 185                        echo "Eh? $f"
 186                        false
 187                        break
 188                else
 189                        git update-index -- $f
 190                fi
 191        done &&
 192        test "$one" = `git hash-object --stdin <one` &&
 193        test "$two" = `git hash-object --stdin <dir/two` &&
 194        differs=`git diff-index --cached HEAD` &&
 195        test -z "$differs" || {
 196                echo Oops "$differs"
 197                false
 198        }
 199'
 200
 201test_expect_success 'apply patch (autocrlf=input)' '
 202
 203        rm -f tmp one dir/two three &&
 204        git config core.autocrlf input &&
 205        git read-tree --reset -u HEAD &&
 206
 207        git apply patch.file &&
 208        test "$patched" = "`git hash-object --stdin <one`" || {
 209                echo "Eh?  apply without index"
 210                false
 211        }
 212'
 213
 214test_expect_success 'apply patch --cached (autocrlf=input)' '
 215
 216        rm -f tmp one dir/two three &&
 217        git config core.autocrlf input &&
 218        git read-tree --reset -u HEAD &&
 219
 220        git apply --cached patch.file &&
 221        test "$patched" = `git rev-parse :one` || {
 222                echo "Eh?  apply with --cached"
 223                false
 224        }
 225'
 226
 227test_expect_success 'apply patch --index (autocrlf=input)' '
 228
 229        rm -f tmp one dir/two three &&
 230        git config core.autocrlf input &&
 231        git read-tree --reset -u HEAD &&
 232
 233        git apply --index patch.file &&
 234        test "$patched" = `git rev-parse :one` &&
 235        test "$patched" = `git hash-object --stdin <one` || {
 236                echo "Eh?  apply with --index"
 237                false
 238        }
 239'
 240
 241test_expect_success 'apply patch (autocrlf=true)' '
 242
 243        rm -f tmp one dir/two three &&
 244        git config core.autocrlf true &&
 245        git read-tree --reset -u HEAD &&
 246
 247        git apply patch.file &&
 248        test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
 249                echo "Eh?  apply without index"
 250                false
 251        }
 252'
 253
 254test_expect_success 'apply patch --cached (autocrlf=true)' '
 255
 256        rm -f tmp one dir/two three &&
 257        git config core.autocrlf true &&
 258        git read-tree --reset -u HEAD &&
 259
 260        git apply --cached patch.file &&
 261        test "$patched" = `git rev-parse :one` || {
 262                echo "Eh?  apply without index"
 263                false
 264        }
 265'
 266
 267test_expect_success 'apply patch --index (autocrlf=true)' '
 268
 269        rm -f tmp one dir/two three &&
 270        git config core.autocrlf true &&
 271        git read-tree --reset -u HEAD &&
 272
 273        git apply --index patch.file &&
 274        test "$patched" = `git rev-parse :one` &&
 275        test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
 276                echo "Eh?  apply with --index"
 277                false
 278        }
 279'
 280
 281test_expect_success '.gitattributes says two is binary' '
 282
 283        rm -f tmp one dir/two three &&
 284        echo "two -crlf" >.gitattributes &&
 285        git config core.autocrlf true &&
 286        git read-tree --reset -u HEAD &&
 287
 288        if remove_cr dir/two >/dev/null
 289        then
 290                echo "Huh?"
 291                false
 292        else
 293                : happy
 294        fi &&
 295
 296        if remove_cr one >/dev/null
 297        then
 298                : happy
 299        else
 300                echo "Huh?"
 301                false
 302        fi &&
 303
 304        if remove_cr three >/dev/null
 305        then
 306                echo "Huh?"
 307                false
 308        else
 309                : happy
 310        fi
 311'
 312
 313test_expect_success '.gitattributes says two is input' '
 314
 315        rm -f tmp one dir/two three &&
 316        echo "two crlf=input" >.gitattributes &&
 317        git read-tree --reset -u HEAD &&
 318
 319        if remove_cr dir/two >/dev/null
 320        then
 321                echo "Huh?"
 322                false
 323        else
 324                : happy
 325        fi
 326'
 327
 328test_expect_success '.gitattributes says two and three are text' '
 329
 330        rm -f tmp one dir/two three &&
 331        echo "t* crlf" >.gitattributes &&
 332        git read-tree --reset -u HEAD &&
 333
 334        if remove_cr dir/two >/dev/null
 335        then
 336                : happy
 337        else
 338                echo "Huh?"
 339                false
 340        fi &&
 341
 342        if remove_cr three >/dev/null
 343        then
 344                : happy
 345        else
 346                echo "Huh?"
 347                false
 348        fi
 349'
 350
 351test_expect_success 'in-tree .gitattributes (1)' '
 352
 353        echo "one -crlf" >>.gitattributes &&
 354        git add .gitattributes &&
 355        git commit -m "Add .gitattributes" &&
 356
 357        rm -rf tmp one dir .gitattributes patch.file three &&
 358        git read-tree --reset -u HEAD &&
 359
 360        if remove_cr one >/dev/null
 361        then
 362                echo "Eh? one should not have CRLF"
 363                false
 364        else
 365                : happy
 366        fi &&
 367        remove_cr three >/dev/null || {
 368                echo "Eh? three should still have CRLF"
 369                false
 370        }
 371'
 372
 373test_expect_success 'in-tree .gitattributes (2)' '
 374
 375        rm -rf tmp one dir .gitattributes patch.file three &&
 376        git read-tree --reset HEAD &&
 377        git checkout-index -f -q -u -a &&
 378
 379        if remove_cr one >/dev/null
 380        then
 381                echo "Eh? one should not have CRLF"
 382                false
 383        else
 384                : happy
 385        fi &&
 386        remove_cr three >/dev/null || {
 387                echo "Eh? three should still have CRLF"
 388                false
 389        }
 390'
 391
 392test_expect_success 'in-tree .gitattributes (3)' '
 393
 394        rm -rf tmp one dir .gitattributes patch.file three &&
 395        git read-tree --reset HEAD &&
 396        git checkout-index -u .gitattributes &&
 397        git checkout-index -u one dir/two three &&
 398
 399        if remove_cr one >/dev/null
 400        then
 401                echo "Eh? one should not have CRLF"
 402                false
 403        else
 404                : happy
 405        fi &&
 406        remove_cr three >/dev/null || {
 407                echo "Eh? three should still have CRLF"
 408                false
 409        }
 410'
 411
 412test_expect_success 'in-tree .gitattributes (4)' '
 413
 414        rm -rf tmp one dir .gitattributes patch.file three &&
 415        git read-tree --reset HEAD &&
 416        git checkout-index -u one dir/two three &&
 417        git checkout-index -u .gitattributes &&
 418
 419        if remove_cr one >/dev/null
 420        then
 421                echo "Eh? one should not have CRLF"
 422                false
 423        else
 424                : happy
 425        fi &&
 426        remove_cr three >/dev/null || {
 427                echo "Eh? three should still have CRLF"
 428                false
 429        }
 430'
 431
 432test_expect_success 'checkout with existing .gitattributes' '
 433
 434        git config core.autocrlf true &&
 435        git config --unset core.safecrlf &&
 436        echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
 437        git add .gitattributes &&
 438        git commit -m initial &&
 439        echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
 440        echo "contents" > .file &&
 441        git add .gitattributes .file &&
 442        git commit -m second &&
 443
 444        git checkout master~1 &&
 445        git checkout master &&
 446        test "$(git diff-files --raw)" = ""
 447
 448'
 449
 450test_expect_success 'checkout when deleting .gitattributes' '
 451
 452        git rm .gitattributes &&
 453        echo "contentsQ" | q_to_cr > .file2 &&
 454        git add .file2 &&
 455        git commit -m third
 456
 457        git checkout master~1 &&
 458        git checkout master &&
 459        remove_cr .file2 >/dev/null
 460
 461'
 462
 463test_expect_success 'invalid .gitattributes (must not crash)' '
 464
 465        echo "three +crlf" >>.gitattributes &&
 466        git diff
 467
 468'
 469
 470test_done