t / t4150-am.shon commit t4150: am --resolved fails if index has no changes (60ff7f9)
   1#!/bin/sh
   2
   3test_description='git am running'
   4
   5. ./test-lib.sh
   6
   7test_expect_success 'setup: messages' '
   8        cat >msg <<-\EOF &&
   9        second
  10
  11        Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
  12        eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
  13        voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
  14        kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
  15        ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
  16        tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
  17        vero eos et accusam et justo duo dolores et ea rebum.
  18
  19        EOF
  20        qz_to_tab_space <<-\EOF >>msg &&
  21        QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
  22        Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
  23        Qat vero eros et accumsan et iusto odio dignissim qui blandit
  24        Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla
  25        Qfacilisi.
  26        EOF
  27        cat >>msg <<-\EOF &&
  28
  29        Lorem ipsum dolor sit amet,
  30        consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
  31        laoreet dolore magna aliquam erat volutpat.
  32
  33          git
  34          ---
  35          +++
  36
  37        Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
  38        lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
  39        dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
  40        dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
  41        dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
  42        feugait nulla facilisi.
  43        EOF
  44
  45        cat >failmail <<-\EOF &&
  46        From foo@example.com Fri May 23 10:43:49 2008
  47        From:   foo@example.com
  48        To:     bar@example.com
  49        Subject: Re: [RFC/PATCH] git-foo.sh
  50        Date:   Fri, 23 May 2008 05:23:42 +0200
  51
  52        Sometimes we have to find out that there'\''s nothing left.
  53
  54        EOF
  55
  56        cat >pine <<-\EOF &&
  57        From MAILER-DAEMON Fri May 23 10:43:49 2008
  58        Date: 23 May 2008 05:23:42 +0200
  59        From: Mail System Internal Data <MAILER-DAEMON@example.com>
  60        Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
  61        Message-ID: <foo-0001@example.com>
  62
  63        This text is part of the internal format of your mail folder, and is not
  64        a real message.  It is created automatically by the mail system software.
  65        If deleted, important folder data will be lost, and it will be re-created
  66        with the data reset to initial values.
  67
  68        EOF
  69
  70        signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
  71'
  72
  73test_expect_success setup '
  74        echo hello >file &&
  75        git add file &&
  76        test_tick &&
  77        git commit -m first &&
  78        git tag first &&
  79
  80        echo world >>file &&
  81        git add file &&
  82        test_tick &&
  83        git commit -s -F msg &&
  84        git tag second &&
  85
  86        git format-patch --stdout first >patch1 &&
  87        {
  88                echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
  89                echo "X-Fake-Field: Line One" &&
  90                echo "X-Fake-Field: Line Two" &&
  91                echo "X-Fake-Field: Line Three" &&
  92                git format-patch --stdout first | sed -e "1d"
  93        } > patch1.eml &&
  94        {
  95                echo "X-Fake-Field: Line One" &&
  96                echo "X-Fake-Field: Line Two" &&
  97                echo "X-Fake-Field: Line Three" &&
  98                git format-patch --stdout first | sed -e "1d"
  99        } | append_cr >patch1-crlf.eml &&
 100        {
 101                printf "%255s\\n" ""
 102                echo "X-Fake-Field: Line One" &&
 103                echo "X-Fake-Field: Line Two" &&
 104                echo "X-Fake-Field: Line Three" &&
 105                git format-patch --stdout first | sed -e "1d"
 106        } > patch1-ws.eml &&
 107
 108        sed -n -e "3,\$p" msg >file &&
 109        git add file &&
 110        test_tick &&
 111        git commit -m third &&
 112
 113        git format-patch --stdout first >patch2 &&
 114
 115        git checkout -b lorem &&
 116        sed -n -e "11,\$p" msg >file &&
 117        head -n 9 msg >>file &&
 118        test_tick &&
 119        git commit -a -m "moved stuff" &&
 120
 121        echo goodbye >another &&
 122        git add another &&
 123        test_tick &&
 124        git commit -m "added another file" &&
 125
 126        git format-patch --stdout master >lorem-move.patch &&
 127        git format-patch --no-prefix --stdout master >lorem-zero.patch &&
 128
 129        git checkout -b rename &&
 130        git mv file renamed &&
 131        git commit -m "renamed a file" &&
 132
 133        git format-patch -M --stdout lorem >rename.patch &&
 134
 135        git reset --soft lorem^ &&
 136        git commit -m "renamed a file and added another" &&
 137
 138        git format-patch -M --stdout lorem^ >rename-add.patch &&
 139
 140        # reset time
 141        sane_unset test_tick &&
 142        test_tick
 143'
 144
 145test_expect_success 'am applies patch correctly' '
 146        rm -fr .git/rebase-apply &&
 147        git reset --hard &&
 148        git checkout first &&
 149        test_tick &&
 150        git am <patch1 &&
 151        test_path_is_missing .git/rebase-apply &&
 152        git diff --exit-code second &&
 153        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 154        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 155'
 156
 157test_expect_success 'am fails if index is dirty' '
 158        test_when_finished "rm -f dirtyfile" &&
 159        rm -fr .git/rebase-apply &&
 160        git reset --hard &&
 161        git checkout first &&
 162        echo dirtyfile >dirtyfile &&
 163        git add dirtyfile &&
 164        test_must_fail git am patch1 &&
 165        test_path_is_dir .git/rebase-apply &&
 166        test_cmp_rev first HEAD
 167'
 168
 169test_expect_success 'am applies patch e-mail not in a mbox' '
 170        rm -fr .git/rebase-apply &&
 171        git reset --hard &&
 172        git checkout first &&
 173        git am patch1.eml &&
 174        test_path_is_missing .git/rebase-apply &&
 175        git diff --exit-code second &&
 176        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 177        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 178'
 179
 180test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
 181        rm -fr .git/rebase-apply &&
 182        git reset --hard &&
 183        git checkout first &&
 184        git am patch1-crlf.eml &&
 185        test_path_is_missing .git/rebase-apply &&
 186        git diff --exit-code second &&
 187        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 188        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 189'
 190
 191test_expect_success 'am applies patch e-mail with preceding whitespace' '
 192        rm -fr .git/rebase-apply &&
 193        git reset --hard &&
 194        git checkout first &&
 195        git am patch1-ws.eml &&
 196        test_path_is_missing .git/rebase-apply &&
 197        git diff --exit-code second &&
 198        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 199        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 200'
 201
 202test_expect_success 'setup: new author and committer' '
 203        GIT_AUTHOR_NAME="Another Thor" &&
 204        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
 205        GIT_COMMITTER_NAME="Co M Miter" &&
 206        GIT_COMMITTER_EMAIL="c.miter@example.com" &&
 207        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 208'
 209
 210compare () {
 211        a=$(git cat-file commit "$2" | grep "^$1 ") &&
 212        b=$(git cat-file commit "$3" | grep "^$1 ") &&
 213        test "$a" = "$b"
 214}
 215
 216test_expect_success 'am changes committer and keeps author' '
 217        test_tick &&
 218        rm -fr .git/rebase-apply &&
 219        git reset --hard &&
 220        git checkout first &&
 221        git am patch2 &&
 222        test_path_is_missing .git/rebase-apply &&
 223        test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
 224        git diff --exit-code master..HEAD &&
 225        git diff --exit-code master^..HEAD^ &&
 226        compare author master HEAD &&
 227        compare author master^ HEAD^ &&
 228        test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
 229             "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
 230'
 231
 232test_expect_success 'am --signoff adds Signed-off-by: line' '
 233        rm -fr .git/rebase-apply &&
 234        git reset --hard &&
 235        git checkout -b master2 first &&
 236        git am --signoff <patch2 &&
 237        printf "%s\n" "$signoff" >expected &&
 238        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
 239        git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
 240        test_cmp expected actual &&
 241        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
 242        git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
 243        test_cmp expected actual
 244'
 245
 246test_expect_success 'am stays in branch' '
 247        echo refs/heads/master2 >expected &&
 248        git symbolic-ref HEAD >actual &&
 249        test_cmp expected actual
 250'
 251
 252test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
 253        git format-patch --stdout HEAD^ >patch3 &&
 254        sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
 255        rm -fr .git/rebase-apply &&
 256        git reset --hard &&
 257        git checkout HEAD^ &&
 258        git am --signoff patch4 &&
 259        git cat-file commit HEAD >actual &&
 260        test $(grep -c "^Signed-off-by:" actual) -eq 1
 261'
 262
 263test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
 264        git rev-parse HEAD >expected &&
 265        git rev-parse master2 >actual &&
 266        test_cmp expected actual
 267'
 268
 269test_expect_success 'am --keep really keeps the subject' '
 270        rm -fr .git/rebase-apply &&
 271        git reset --hard &&
 272        git checkout HEAD^ &&
 273        git am --keep patch4 &&
 274        test_path_is_missing .git/rebase-apply &&
 275        git cat-file commit HEAD >actual &&
 276        grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
 277'
 278
 279test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
 280        rm -fr .git/rebase-apply &&
 281        git reset --hard &&
 282        git checkout HEAD^ &&
 283        git am --keep-non-patch patch4 &&
 284        test_path_is_missing .git/rebase-apply &&
 285        git cat-file commit HEAD >actual &&
 286        grep "^\[foo\] third" actual
 287'
 288
 289test_expect_success 'setup am -3' '
 290        rm -fr .git/rebase-apply &&
 291        git reset --hard &&
 292        git checkout -b base3way master2 &&
 293        sed -n -e "3,\$p" msg >file &&
 294        head -n 9 msg >>file &&
 295        git add file &&
 296        test_tick &&
 297        git commit -m "copied stuff"
 298'
 299
 300test_expect_success 'am -3 falls back to 3-way merge' '
 301        rm -fr .git/rebase-apply &&
 302        git reset --hard &&
 303        git checkout -b lorem2 base3way &&
 304        git am -3 lorem-move.patch &&
 305        test_path_is_missing .git/rebase-apply &&
 306        git diff --exit-code lorem
 307'
 308
 309test_expect_success 'am -3 -p0 can read --no-prefix patch' '
 310        rm -fr .git/rebase-apply &&
 311        git reset --hard &&
 312        git checkout -b lorem3 base3way &&
 313        git am -3 -p0 lorem-zero.patch &&
 314        test_path_is_missing .git/rebase-apply &&
 315        git diff --exit-code lorem
 316'
 317
 318test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
 319        rm -fr .git/rebase-apply &&
 320        git reset --hard &&
 321        git checkout -b lorem4 base3way &&
 322        test_config am.threeWay 1 &&
 323        git am lorem-move.patch &&
 324        test_path_is_missing .git/rebase-apply &&
 325        git diff --exit-code lorem
 326'
 327
 328test_expect_success 'am with config am.threeWay overridden by --no-3way' '
 329        rm -fr .git/rebase-apply &&
 330        git reset --hard &&
 331        git checkout -b lorem5 base3way &&
 332        test_config am.threeWay 1 &&
 333        test_must_fail git am --no-3way lorem-move.patch &&
 334        test_path_is_dir .git/rebase-apply
 335'
 336
 337test_expect_success 'am can rename a file' '
 338        grep "^rename from" rename.patch &&
 339        rm -fr .git/rebase-apply &&
 340        git reset --hard &&
 341        git checkout lorem^0 &&
 342        git am rename.patch &&
 343        test_path_is_missing .git/rebase-apply &&
 344        git update-index --refresh &&
 345        git diff --exit-code rename
 346'
 347
 348test_expect_success 'am -3 can rename a file' '
 349        grep "^rename from" rename.patch &&
 350        rm -fr .git/rebase-apply &&
 351        git reset --hard &&
 352        git checkout lorem^0 &&
 353        git am -3 rename.patch &&
 354        test_path_is_missing .git/rebase-apply &&
 355        git update-index --refresh &&
 356        git diff --exit-code rename
 357'
 358
 359test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
 360        grep "^rename from" rename-add.patch &&
 361        rm -fr .git/rebase-apply &&
 362        git reset --hard &&
 363        git checkout lorem^0 &&
 364        git am -3 rename-add.patch &&
 365        test_path_is_missing .git/rebase-apply &&
 366        git update-index --refresh &&
 367        git diff --exit-code rename
 368'
 369
 370test_expect_success 'am -3 -q is quiet' '
 371        rm -fr .git/rebase-apply &&
 372        git checkout -f lorem2 &&
 373        git reset base3way --hard &&
 374        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 375        ! test -s output.out
 376'
 377
 378test_expect_success 'am pauses on conflict' '
 379        rm -fr .git/rebase-apply &&
 380        git reset --hard &&
 381        git checkout lorem2^^ &&
 382        test_must_fail git am lorem-move.patch &&
 383        test -d .git/rebase-apply
 384'
 385
 386test_expect_success 'am --skip works' '
 387        echo goodbye >expected &&
 388        git am --skip &&
 389        test_path_is_missing .git/rebase-apply &&
 390        git diff --exit-code lorem2^^ -- file &&
 391        test_cmp expected another
 392'
 393
 394test_expect_success 'am --abort removes a stray directory' '
 395        mkdir .git/rebase-apply &&
 396        git am --abort &&
 397        test_path_is_missing .git/rebase-apply
 398'
 399
 400test_expect_success 'am refuses patches when paused' '
 401        rm -fr .git/rebase-apply &&
 402        git reset --hard &&
 403        git checkout lorem2^^ &&
 404
 405        test_must_fail git am lorem-move.patch &&
 406        test_path_is_dir .git/rebase-apply &&
 407        test_cmp_rev lorem2^^ HEAD &&
 408
 409        test_must_fail git am <lorem-move.patch &&
 410        test_path_is_dir .git/rebase-apply &&
 411        test_cmp_rev lorem2^^ HEAD
 412'
 413
 414test_expect_success 'am --resolved works' '
 415        echo goodbye >expected &&
 416        rm -fr .git/rebase-apply &&
 417        git reset --hard &&
 418        git checkout lorem2^^ &&
 419        test_must_fail git am lorem-move.patch &&
 420        test -d .git/rebase-apply &&
 421        echo resolved >>file &&
 422        git add file &&
 423        git am --resolved &&
 424        test_path_is_missing .git/rebase-apply &&
 425        test_cmp expected another
 426'
 427
 428test_expect_success 'am --resolved fails if index has no changes' '
 429        rm -fr .git/rebase-apply &&
 430        git reset --hard &&
 431        git checkout lorem2^^ &&
 432        test_must_fail git am lorem-move.patch &&
 433        test_path_is_dir .git/rebase-apply &&
 434        test_cmp_rev lorem2^^ HEAD &&
 435        test_must_fail git am --resolved &&
 436        test_path_is_dir .git/rebase-apply &&
 437        test_cmp_rev lorem2^^ HEAD
 438'
 439
 440test_expect_success 'am takes patches from a Pine mailbox' '
 441        rm -fr .git/rebase-apply &&
 442        git reset --hard &&
 443        git checkout first &&
 444        cat pine patch1 | git am &&
 445        test_path_is_missing .git/rebase-apply &&
 446        git diff --exit-code master^..HEAD
 447'
 448
 449test_expect_success 'am fails on mail without patch' '
 450        rm -fr .git/rebase-apply &&
 451        git reset --hard &&
 452        test_must_fail git am <failmail &&
 453        git am --abort &&
 454        test_path_is_missing .git/rebase-apply
 455'
 456
 457test_expect_success 'am fails on empty patch' '
 458        rm -fr .git/rebase-apply &&
 459        git reset --hard &&
 460        echo "---" >>failmail &&
 461        test_must_fail git am <failmail &&
 462        git am --skip &&
 463        test_path_is_missing .git/rebase-apply
 464'
 465
 466test_expect_success 'am works from stdin in subdirectory' '
 467        rm -fr subdir &&
 468        rm -fr .git/rebase-apply &&
 469        git reset --hard &&
 470        git checkout first &&
 471        (
 472                mkdir -p subdir &&
 473                cd subdir &&
 474                git am <../patch1
 475        ) &&
 476        git diff --exit-code second
 477'
 478
 479test_expect_success 'am works from file (relative path given) in subdirectory' '
 480        rm -fr subdir &&
 481        rm -fr .git/rebase-apply &&
 482        git reset --hard &&
 483        git checkout first &&
 484        (
 485                mkdir -p subdir &&
 486                cd subdir &&
 487                git am ../patch1
 488        ) &&
 489        git diff --exit-code second
 490'
 491
 492test_expect_success 'am works from file (absolute path given) in subdirectory' '
 493        rm -fr subdir &&
 494        rm -fr .git/rebase-apply &&
 495        git reset --hard &&
 496        git checkout first &&
 497        P=$(pwd) &&
 498        (
 499                mkdir -p subdir &&
 500                cd subdir &&
 501                git am "$P/patch1"
 502        ) &&
 503        git diff --exit-code second
 504'
 505
 506test_expect_success 'am --committer-date-is-author-date' '
 507        rm -fr .git/rebase-apply &&
 508        git reset --hard &&
 509        git checkout first &&
 510        test_tick &&
 511        git am --committer-date-is-author-date patch1 &&
 512        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 513        sed -ne "/^author /s/.*> //p" head1 >at &&
 514        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 515        test_cmp at ct
 516'
 517
 518test_expect_success 'am without --committer-date-is-author-date' '
 519        rm -fr .git/rebase-apply &&
 520        git reset --hard &&
 521        git checkout first &&
 522        test_tick &&
 523        git am patch1 &&
 524        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 525        sed -ne "/^author /s/.*> //p" head1 >at &&
 526        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 527        ! test_cmp at ct
 528'
 529
 530# This checks for +0000 because TZ is set to UTC and that should
 531# show up when the current time is used. The date in message is set
 532# by test_tick that uses -0700 timezone; if this feature does not
 533# work, we will see that instead of +0000.
 534test_expect_success 'am --ignore-date' '
 535        rm -fr .git/rebase-apply &&
 536        git reset --hard &&
 537        git checkout first &&
 538        test_tick &&
 539        git am --ignore-date patch1 &&
 540        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 541        sed -ne "/^author /s/.*> //p" head1 >at &&
 542        grep "+0000" at
 543'
 544
 545test_expect_success 'am into an unborn branch' '
 546        git rev-parse first^{tree} >expected &&
 547        rm -fr .git/rebase-apply &&
 548        git reset --hard &&
 549        rm -fr subdir &&
 550        mkdir subdir &&
 551        git format-patch --numbered-files -o subdir -1 first &&
 552        (
 553                cd subdir &&
 554                git init &&
 555                git am 1
 556        ) &&
 557        (
 558                cd subdir &&
 559                git rev-parse HEAD^{tree} >../actual
 560        ) &&
 561        test_cmp expected actual
 562'
 563
 564test_expect_success 'am newline in subject' '
 565        rm -fr .git/rebase-apply &&
 566        git reset --hard &&
 567        git checkout first &&
 568        test_tick &&
 569        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 570        git am <patchnl >output.out 2>&1 &&
 571        test_i18ngrep "^Applying: second \\\n foo$" output.out
 572'
 573
 574test_expect_success 'am -q is quiet' '
 575        rm -fr .git/rebase-apply &&
 576        git reset --hard &&
 577        git checkout first &&
 578        test_tick &&
 579        git am -q <patch1 >output.out 2>&1 &&
 580        ! test -s output.out
 581'
 582
 583test_expect_success 'am empty-file does not infloop' '
 584        rm -fr .git/rebase-apply &&
 585        git reset --hard &&
 586        touch empty-file &&
 587        test_tick &&
 588        test_must_fail git am empty-file 2>actual &&
 589        echo Patch format detection failed. >expected &&
 590        test_i18ncmp expected actual
 591'
 592
 593test_expect_success 'am --message-id really adds the message id' '
 594        rm -fr .git/rebase-apply &&
 595        git reset --hard &&
 596        git checkout HEAD^ &&
 597        git am --message-id patch1.eml &&
 598        test_path_is_missing .git/rebase-apply &&
 599        git cat-file commit HEAD | tail -n1 >actual &&
 600        grep Message-Id patch1.eml >expected &&
 601        test_cmp expected actual
 602'
 603
 604test_expect_success 'am.messageid really adds the message id' '
 605        rm -fr .git/rebase-apply &&
 606        git reset --hard &&
 607        git checkout HEAD^ &&
 608        test_config am.messageid true &&
 609        git am patch1.eml &&
 610        test_path_is_missing .git/rebase-apply &&
 611        git cat-file commit HEAD | tail -n1 >actual &&
 612        grep Message-Id patch1.eml >expected &&
 613        test_cmp expected actual
 614'
 615
 616test_expect_success 'am --message-id -s signs off after the message id' '
 617        rm -fr .git/rebase-apply &&
 618        git reset --hard &&
 619        git checkout HEAD^ &&
 620        git am -s --message-id patch1.eml &&
 621        test_path_is_missing .git/rebase-apply &&
 622        git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
 623        grep Message-Id patch1.eml >expected &&
 624        test_cmp expected actual
 625'
 626
 627test_done