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