t / t0020-crlf.shon commit t0020-crlf: check the right file (30612cb)
   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
  11# add or remove CRs to disk file in-place
  12# usage: munge_cr <append|remove> <file>
  13munge_cr () {
  14        "${1}_cr" <"$2" >tmp &&
  15        mv tmp "$2"
  16}
  17
  18test_expect_success setup '
  19
  20        git config core.autocrlf false &&
  21
  22        for w in Hello world how are you; do echo $w; done >one &&
  23        mkdir dir &&
  24        for w in I am very very fine thank you; do echo $w; done >dir/two &&
  25        for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&
  26        git add . &&
  27
  28        git commit -m initial &&
  29
  30        one=$(git rev-parse HEAD:one) &&
  31        dir=$(git rev-parse HEAD:dir) &&
  32        two=$(git rev-parse HEAD:dir/two) &&
  33        three=$(git rev-parse HEAD:three) &&
  34
  35        for w in Some extra lines here; do echo $w; done >>one &&
  36        git diff >patch.file &&
  37        patched=$(git hash-object --stdin <one) &&
  38        git read-tree --reset -u HEAD &&
  39
  40        echo happy.
  41'
  42
  43test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
  44
  45        git config core.autocrlf input &&
  46        git config core.safecrlf true &&
  47
  48        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
  49        test_must_fail git add allcrlf
  50'
  51
  52test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
  53
  54        git config core.autocrlf input &&
  55        git config core.safecrlf true &&
  56
  57        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  58        test_must_fail git add mixed
  59'
  60
  61test_expect_success 'safecrlf: autocrlf=true, all LF' '
  62
  63        git config core.autocrlf true &&
  64        git config core.safecrlf true &&
  65
  66        for w in I am all LF; do echo $w; done >alllf &&
  67        test_must_fail git add alllf
  68'
  69
  70test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
  71
  72        git config core.autocrlf true &&
  73        git config core.safecrlf true &&
  74
  75        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
  76        test_must_fail git add mixed
  77'
  78
  79test_expect_success 'safecrlf: print warning only once' '
  80
  81        git config core.autocrlf input &&
  82        git config core.safecrlf warn &&
  83
  84        for w in I am all LF; do echo $w; done >doublewarn &&
  85        git add doublewarn &&
  86        git commit -m "nowarn" &&
  87        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
  88        test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1
  89'
  90
  91
  92test_expect_success 'safecrlf: git diff demotes safecrlf=true to warn' '
  93        git config core.autocrlf input &&
  94        git config core.safecrlf true &&
  95        git diff HEAD
  96'
  97
  98
  99test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
 100        git config core.autocrlf false &&
 101        git config core.safecrlf false &&
 102        git reset --hard HEAD^
 103'
 104
 105test_expect_success 'update with autocrlf=input' '
 106
 107        rm -f tmp one dir/two three &&
 108        git read-tree --reset -u HEAD &&
 109        git config core.autocrlf input &&
 110        munge_cr append one &&
 111        munge_cr append dir/two &&
 112        git update-index -- one dir/two &&
 113        differs=$(git diff-index --cached HEAD) &&
 114        verbose test -z "$differs"
 115
 116'
 117
 118test_expect_success 'update with autocrlf=true' '
 119
 120        rm -f tmp one dir/two three &&
 121        git read-tree --reset -u HEAD &&
 122        git config core.autocrlf true &&
 123        munge_cr append one &&
 124        munge_cr append dir/two &&
 125        git update-index -- one dir/two &&
 126        differs=$(git diff-index --cached HEAD) &&
 127        verbose test -z "$differs"
 128
 129'
 130
 131test_expect_success 'checkout with autocrlf=true' '
 132
 133        rm -f tmp one dir/two three &&
 134        git config core.autocrlf true &&
 135        git read-tree --reset -u HEAD &&
 136        munge_cr remove one &&
 137        munge_cr remove dir/two &&
 138        git update-index -- one dir/two &&
 139        test "$one" = $(git hash-object --stdin <one) &&
 140        test "$two" = $(git hash-object --stdin <dir/two) &&
 141        differs=$(git diff-index --cached HEAD) &&
 142        verbose test -z "$differs"
 143'
 144
 145test_expect_success 'checkout with autocrlf=input' '
 146
 147        rm -f tmp one dir/two three &&
 148        git config core.autocrlf input &&
 149        git read-tree --reset -u HEAD &&
 150        test_must_fail has_cr one &&
 151        test_must_fail has_cr dir/two &&
 152        git update-index -- one dir/two &&
 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        verbose test -z "$differs"
 157'
 158
 159test_expect_success 'apply patch (autocrlf=input)' '
 160
 161        rm -f tmp one dir/two three &&
 162        git config core.autocrlf input &&
 163        git read-tree --reset -u HEAD &&
 164
 165        git apply patch.file &&
 166        verbose test "$patched" = "$(git hash-object --stdin <one)"
 167'
 168
 169test_expect_success 'apply patch --cached (autocrlf=input)' '
 170
 171        rm -f tmp one dir/two three &&
 172        git config core.autocrlf input &&
 173        git read-tree --reset -u HEAD &&
 174
 175        git apply --cached patch.file &&
 176        verbose test "$patched" = $(git rev-parse :one)
 177'
 178
 179test_expect_success 'apply patch --index (autocrlf=input)' '
 180
 181        rm -f tmp one dir/two three &&
 182        git config core.autocrlf input &&
 183        git read-tree --reset -u HEAD &&
 184
 185        git apply --index patch.file &&
 186        verbose test "$patched" = $(git rev-parse :one) &&
 187        verbose test "$patched" = $(git hash-object --stdin <one)
 188'
 189
 190test_expect_success 'apply patch (autocrlf=true)' '
 191
 192        rm -f tmp one dir/two three &&
 193        git config core.autocrlf true &&
 194        git read-tree --reset -u HEAD &&
 195
 196        git apply patch.file &&
 197        verbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"
 198'
 199
 200test_expect_success 'apply patch --cached (autocrlf=true)' '
 201
 202        rm -f tmp one dir/two three &&
 203        git config core.autocrlf true &&
 204        git read-tree --reset -u HEAD &&
 205
 206        git apply --cached patch.file &&
 207        verbose test "$patched" = $(git rev-parse :one)
 208'
 209
 210test_expect_success 'apply patch --index (autocrlf=true)' '
 211
 212        rm -f tmp one dir/two three &&
 213        git config core.autocrlf true &&
 214        git read-tree --reset -u HEAD &&
 215
 216        git apply --index patch.file &&
 217        verbose test "$patched" = $(git rev-parse :one) &&
 218        verbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"
 219'
 220
 221test_expect_success '.gitattributes says two is binary' '
 222
 223        rm -f tmp one dir/two three &&
 224        echo "two -crlf" >.gitattributes &&
 225        git config core.autocrlf true &&
 226        git read-tree --reset -u HEAD &&
 227
 228        if has_cr dir/two
 229        then
 230                echo "Huh?"
 231                false
 232        else
 233                : happy
 234        fi &&
 235
 236        if has_cr one
 237        then
 238                : happy
 239        else
 240                echo "Huh?"
 241                false
 242        fi &&
 243
 244        if has_cr three
 245        then
 246                echo "Huh?"
 247                false
 248        else
 249                : happy
 250        fi
 251'
 252
 253test_expect_success '.gitattributes says two is input' '
 254
 255        rm -f tmp one dir/two three &&
 256        echo "two crlf=input" >.gitattributes &&
 257        git read-tree --reset -u HEAD &&
 258
 259        if has_cr dir/two
 260        then
 261                echo "Huh?"
 262                false
 263        else
 264                : happy
 265        fi
 266'
 267
 268test_expect_success '.gitattributes says two and three are text' '
 269
 270        rm -f tmp one dir/two three &&
 271        echo "t* crlf" >.gitattributes &&
 272        git read-tree --reset -u HEAD &&
 273
 274        verbose has_cr dir/two &&
 275        verbose has_cr three
 276'
 277
 278test_expect_success 'in-tree .gitattributes (1)' '
 279
 280        echo "one -crlf" >>.gitattributes &&
 281        git add .gitattributes &&
 282        git commit -m "Add .gitattributes" &&
 283
 284        rm -rf tmp one dir .gitattributes patch.file three &&
 285        git read-tree --reset -u HEAD &&
 286
 287        test_must_fail has_cr one &&
 288        verbose has_cr three
 289'
 290
 291test_expect_success 'in-tree .gitattributes (2)' '
 292
 293        rm -rf tmp one dir .gitattributes patch.file three &&
 294        git read-tree --reset HEAD &&
 295        git checkout-index -f -q -u -a &&
 296
 297        test_must_fail has_cr one &&
 298        verbose has_cr three
 299'
 300
 301test_expect_success 'in-tree .gitattributes (3)' '
 302
 303        rm -rf tmp one dir .gitattributes patch.file three &&
 304        git read-tree --reset HEAD &&
 305        git checkout-index -u .gitattributes &&
 306        git checkout-index -u one dir/two three &&
 307
 308        test_must_fail has_cr one &&
 309        verbose has_cr three
 310'
 311
 312test_expect_success 'in-tree .gitattributes (4)' '
 313
 314        rm -rf tmp one dir .gitattributes patch.file three &&
 315        git read-tree --reset HEAD &&
 316        git checkout-index -u one dir/two three &&
 317        git checkout-index -u .gitattributes &&
 318
 319        test_must_fail has_cr one &&
 320        verbose has_cr three
 321'
 322
 323test_expect_success 'checkout with existing .gitattributes' '
 324
 325        git config core.autocrlf true &&
 326        git config --unset core.safecrlf &&
 327        echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
 328        git add .gitattributes &&
 329        git commit -m initial &&
 330        echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
 331        echo "contents" > .file &&
 332        git add .gitattributes .file &&
 333        git commit -m second &&
 334
 335        git checkout master~1 &&
 336        git checkout master &&
 337        test "$(git diff-files --raw)" = ""
 338
 339'
 340
 341test_expect_success 'checkout when deleting .gitattributes' '
 342
 343        git rm .gitattributes &&
 344        echo "contentsQ" | q_to_cr > .file2 &&
 345        git add .file2 &&
 346        git commit -m third &&
 347
 348        git checkout master~1 &&
 349        git checkout master &&
 350        has_cr .file2
 351
 352'
 353
 354test_expect_success 'invalid .gitattributes (must not crash)' '
 355
 356        echo "three +crlf" >>.gitattributes &&
 357        git diff
 358
 359'
 360# Some more tests here to add new autocrlf functionality.
 361# We want to have a known state here, so start a bit from scratch
 362
 363test_expect_success 'setting up for new autocrlf tests' '
 364        git config core.autocrlf false &&
 365        git config core.safecrlf false &&
 366        rm -rf .????* * &&
 367        for w in I am all LF; do echo $w; done >alllf &&
 368        for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
 369        for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
 370        git add -A . &&
 371        git commit -m "alllf, allcrlf and mixed only" &&
 372        git tag -a -m "message" autocrlf-checkpoint
 373'
 374
 375test_expect_success 'report no change after setting autocrlf' '
 376        git config core.autocrlf true &&
 377        touch * &&
 378        git diff --exit-code
 379'
 380
 381test_expect_success 'files are clean after checkout' '
 382        rm * &&
 383        git checkout -f &&
 384        git diff --exit-code
 385'
 386
 387cr_to_Q_no_NL () {
 388    tr '\015' Q | tr -d '\012'
 389}
 390
 391test_expect_success 'LF only file gets CRLF with autocrlf' '
 392        test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
 393'
 394
 395test_expect_success 'Mixed file is still mixed with autocrlf' '
 396        test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
 397'
 398
 399test_expect_success 'CRLF only file has CRLF with autocrlf' '
 400        test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
 401'
 402
 403test_expect_success 'New CRLF file gets LF in repo' '
 404        tr -d "\015" < alllf | append_cr > alllf2 &&
 405        git add alllf2 &&
 406        git commit -m "alllf2 added" &&
 407        git config core.autocrlf false &&
 408        rm * &&
 409        git checkout -f &&
 410        test_cmp alllf alllf2
 411'
 412
 413test_done