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