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