t / t4150-am.shon commit Merge branch 'ag/rebase-i-in-c' into js/rebase-in-c-5.5-work-with-rebase-i-in-c (5ab7e0f)
   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
  44        Reported-by: A N Other <a.n.other@example.com>
  45        EOF
  46
  47        cat >failmail <<-\EOF &&
  48        From foo@example.com Fri May 23 10:43:49 2008
  49        From:   foo@example.com
  50        To:     bar@example.com
  51        Subject: Re: [RFC/PATCH] git-foo.sh
  52        Date:   Fri, 23 May 2008 05:23:42 +0200
  53
  54        Sometimes we have to find out that there'\''s nothing left.
  55
  56        EOF
  57
  58        cat >pine <<-\EOF &&
  59        From MAILER-DAEMON Fri May 23 10:43:49 2008
  60        Date: 23 May 2008 05:23:42 +0200
  61        From: Mail System Internal Data <MAILER-DAEMON@example.com>
  62        Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
  63        Message-ID: <foo-0001@example.com>
  64
  65        This text is part of the internal format of your mail folder, and is not
  66        a real message.  It is created automatically by the mail system software.
  67        If deleted, important folder data will be lost, and it will be re-created
  68        with the data reset to initial values.
  69
  70        EOF
  71
  72        cat >scissors-msg <<-\EOF &&
  73        Test git-am with scissors line
  74
  75        This line should be included in the commit message.
  76        EOF
  77
  78        cat - scissors-msg >no-scissors-msg <<-\EOF &&
  79        This line should not be included in the commit message with --scissors enabled.
  80
  81         - - >8 - - remove everything above this line - - >8 - -
  82
  83        EOF
  84
  85        signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
  86'
  87
  88test_expect_success setup '
  89        echo hello >file &&
  90        git add file &&
  91        test_tick &&
  92        git commit -m first &&
  93        git tag first &&
  94
  95        echo world >>file &&
  96        git add file &&
  97        test_tick &&
  98        git commit -F msg &&
  99        git tag second &&
 100
 101        git format-patch --stdout first >patch1 &&
 102        {
 103                echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
 104                echo "X-Fake-Field: Line One" &&
 105                echo "X-Fake-Field: Line Two" &&
 106                echo "X-Fake-Field: Line Three" &&
 107                git format-patch --stdout first | sed -e "1d"
 108        } > patch1.eml &&
 109        {
 110                echo "X-Fake-Field: Line One" &&
 111                echo "X-Fake-Field: Line Two" &&
 112                echo "X-Fake-Field: Line Three" &&
 113                git format-patch --stdout first | sed -e "1d"
 114        } | append_cr >patch1-crlf.eml &&
 115        {
 116                printf "%255s\\n" ""
 117                echo "X-Fake-Field: Line One" &&
 118                echo "X-Fake-Field: Line Two" &&
 119                echo "X-Fake-Field: Line Three" &&
 120                git format-patch --stdout first | sed -e "1d"
 121        } > patch1-ws.eml &&
 122        {
 123                sed -ne "1p" msg &&
 124                echo &&
 125                echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
 126                echo "Date: $GIT_AUTHOR_DATE" &&
 127                echo &&
 128                sed -e "1,2d" msg &&
 129                echo "---" &&
 130                git diff-tree --no-commit-id --stat -p second
 131        } >patch1-stgit.eml &&
 132        mkdir stgit-series &&
 133        cp patch1-stgit.eml stgit-series/patch &&
 134        {
 135                echo "# This series applies on GIT commit $(git rev-parse first)" &&
 136                echo "patch"
 137        } >stgit-series/series &&
 138        {
 139                echo "# HG changeset patch" &&
 140                echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
 141                echo "# Date $test_tick 25200" &&
 142                echo "#      $(git show --pretty="%aD" -s second)" &&
 143                echo "# Node ID $ZERO_OID" &&
 144                echo "# Parent  $ZERO_OID" &&
 145                cat msg &&
 146                echo &&
 147                git diff-tree --no-commit-id -p second
 148        } >patch1-hg.eml &&
 149
 150
 151        echo scissors-file >scissors-file &&
 152        git add scissors-file &&
 153        git commit -F scissors-msg &&
 154        git tag scissors &&
 155        git format-patch --stdout scissors^ >scissors-patch.eml &&
 156        git reset --hard HEAD^ &&
 157
 158        echo no-scissors-file >no-scissors-file &&
 159        git add no-scissors-file &&
 160        git commit -F no-scissors-msg &&
 161        git tag no-scissors &&
 162        git format-patch --stdout no-scissors^ >no-scissors-patch.eml &&
 163        git reset --hard HEAD^ &&
 164
 165        sed -n -e "3,\$p" msg >file &&
 166        git add file &&
 167        test_tick &&
 168        git commit -m third &&
 169
 170        git format-patch --stdout first >patch2 &&
 171
 172        git checkout -b lorem &&
 173        sed -n -e "11,\$p" msg >file &&
 174        head -n 9 msg >>file &&
 175        test_tick &&
 176        git commit -a -m "moved stuff" &&
 177
 178        echo goodbye >another &&
 179        git add another &&
 180        test_tick &&
 181        git commit -m "added another file" &&
 182
 183        git format-patch --stdout master >lorem-move.patch &&
 184        git format-patch --no-prefix --stdout master >lorem-zero.patch &&
 185
 186        git checkout -b rename &&
 187        git mv file renamed &&
 188        git commit -m "renamed a file" &&
 189
 190        git format-patch -M --stdout lorem >rename.patch &&
 191
 192        git reset --soft lorem^ &&
 193        git commit -m "renamed a file and added another" &&
 194
 195        git format-patch -M --stdout lorem^ >rename-add.patch &&
 196
 197        # reset time
 198        sane_unset test_tick &&
 199        test_tick
 200'
 201
 202test_expect_success 'am applies patch correctly' '
 203        rm -fr .git/rebase-apply &&
 204        git reset --hard &&
 205        git checkout first &&
 206        test_tick &&
 207        git am <patch1 &&
 208        test_path_is_missing .git/rebase-apply &&
 209        git diff --exit-code second &&
 210        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 211        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 212'
 213
 214test_expect_success 'am fails if index is dirty' '
 215        test_when_finished "rm -f dirtyfile" &&
 216        rm -fr .git/rebase-apply &&
 217        git reset --hard &&
 218        git checkout first &&
 219        echo dirtyfile >dirtyfile &&
 220        git add dirtyfile &&
 221        test_must_fail git am patch1 &&
 222        test_path_is_dir .git/rebase-apply &&
 223        test_cmp_rev first HEAD
 224'
 225
 226test_expect_success 'am applies patch e-mail not in a mbox' '
 227        rm -fr .git/rebase-apply &&
 228        git reset --hard &&
 229        git checkout first &&
 230        git am patch1.eml &&
 231        test_path_is_missing .git/rebase-apply &&
 232        git diff --exit-code second &&
 233        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 234        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 235'
 236
 237test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
 238        rm -fr .git/rebase-apply &&
 239        git reset --hard &&
 240        git checkout first &&
 241        git am patch1-crlf.eml &&
 242        test_path_is_missing .git/rebase-apply &&
 243        git diff --exit-code second &&
 244        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 245        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 246'
 247
 248test_expect_success 'am applies patch e-mail with preceding whitespace' '
 249        rm -fr .git/rebase-apply &&
 250        git reset --hard &&
 251        git checkout first &&
 252        git am patch1-ws.eml &&
 253        test_path_is_missing .git/rebase-apply &&
 254        git diff --exit-code second &&
 255        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 256        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 257'
 258
 259test_expect_success 'am applies stgit patch' '
 260        rm -fr .git/rebase-apply &&
 261        git checkout -f first &&
 262        git am patch1-stgit.eml &&
 263        test_path_is_missing .git/rebase-apply &&
 264        git diff --exit-code second &&
 265        test_cmp_rev second HEAD &&
 266        test_cmp_rev second^ HEAD^
 267'
 268
 269test_expect_success 'am --patch-format=stgit applies stgit patch' '
 270        rm -fr .git/rebase-apply &&
 271        git checkout -f first &&
 272        git am --patch-format=stgit <patch1-stgit.eml &&
 273        test_path_is_missing .git/rebase-apply &&
 274        git diff --exit-code second &&
 275        test_cmp_rev second HEAD &&
 276        test_cmp_rev second^ HEAD^
 277'
 278
 279test_expect_success 'am applies stgit series' '
 280        rm -fr .git/rebase-apply &&
 281        git checkout -f first &&
 282        git am stgit-series/series &&
 283        test_path_is_missing .git/rebase-apply &&
 284        git diff --exit-code second &&
 285        test_cmp_rev second HEAD &&
 286        test_cmp_rev second^ HEAD^
 287'
 288
 289test_expect_success 'am applies hg patch' '
 290        rm -fr .git/rebase-apply &&
 291        git checkout -f first &&
 292        git am patch1-hg.eml &&
 293        test_path_is_missing .git/rebase-apply &&
 294        git diff --exit-code second &&
 295        test_cmp_rev second HEAD &&
 296        test_cmp_rev second^ HEAD^
 297'
 298
 299test_expect_success 'am --patch-format=hg applies hg patch' '
 300        rm -fr .git/rebase-apply &&
 301        git checkout -f first &&
 302        git am --patch-format=hg <patch1-hg.eml &&
 303        test_path_is_missing .git/rebase-apply &&
 304        git diff --exit-code second &&
 305        test_cmp_rev second HEAD &&
 306        test_cmp_rev second^ HEAD^
 307'
 308
 309test_expect_success 'am with applypatch-msg hook' '
 310        test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 311        rm -fr .git/rebase-apply &&
 312        git reset --hard &&
 313        git checkout first &&
 314        mkdir -p .git/hooks &&
 315        write_script .git/hooks/applypatch-msg <<-\EOF &&
 316        cat "$1" >actual-msg &&
 317        echo hook-message >"$1"
 318        EOF
 319        git am patch1 &&
 320        test_path_is_missing .git/rebase-apply &&
 321        git diff --exit-code second &&
 322        echo hook-message >expected &&
 323        git log -1 --format=format:%B >actual &&
 324        test_cmp expected actual &&
 325        git log -1 --format=format:%B second >expected &&
 326        test_cmp expected actual-msg
 327'
 328
 329test_expect_success 'am with failing applypatch-msg hook' '
 330        test_when_finished "rm -f .git/hooks/applypatch-msg" &&
 331        rm -fr .git/rebase-apply &&
 332        git reset --hard &&
 333        git checkout first &&
 334        mkdir -p .git/hooks &&
 335        write_script .git/hooks/applypatch-msg <<-\EOF &&
 336        exit 1
 337        EOF
 338        test_must_fail git am patch1 &&
 339        test_path_is_dir .git/rebase-apply &&
 340        git diff --exit-code first &&
 341        test_cmp_rev first HEAD
 342'
 343
 344test_expect_success 'am with pre-applypatch hook' '
 345        test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 346        rm -fr .git/rebase-apply &&
 347        git reset --hard &&
 348        git checkout first &&
 349        mkdir -p .git/hooks &&
 350        write_script .git/hooks/pre-applypatch <<-\EOF &&
 351        git diff first >diff.actual
 352        exit 0
 353        EOF
 354        git am patch1 &&
 355        test_path_is_missing .git/rebase-apply &&
 356        git diff --exit-code second &&
 357        test_cmp_rev second HEAD &&
 358        git diff first..second >diff.expected &&
 359        test_cmp diff.expected diff.actual
 360'
 361
 362test_expect_success 'am with failing pre-applypatch hook' '
 363        test_when_finished "rm -f .git/hooks/pre-applypatch" &&
 364        rm -fr .git/rebase-apply &&
 365        git reset --hard &&
 366        git checkout first &&
 367        mkdir -p .git/hooks &&
 368        write_script .git/hooks/pre-applypatch <<-\EOF &&
 369        exit 1
 370        EOF
 371        test_must_fail git am patch1 &&
 372        test_path_is_dir .git/rebase-apply &&
 373        git diff --exit-code second &&
 374        test_cmp_rev first HEAD
 375'
 376
 377test_expect_success 'am with post-applypatch hook' '
 378        test_when_finished "rm -f .git/hooks/post-applypatch" &&
 379        rm -fr .git/rebase-apply &&
 380        git reset --hard &&
 381        git checkout first &&
 382        mkdir -p .git/hooks &&
 383        write_script .git/hooks/post-applypatch <<-\EOF &&
 384        git rev-parse HEAD >head.actual
 385        git diff second >diff.actual
 386        exit 0
 387        EOF
 388        git am patch1 &&
 389        test_path_is_missing .git/rebase-apply &&
 390        test_cmp_rev second HEAD &&
 391        git rev-parse second >head.expected &&
 392        test_cmp head.expected head.actual &&
 393        git diff second >diff.expected &&
 394        test_cmp diff.expected diff.actual
 395'
 396
 397test_expect_success 'am with failing post-applypatch hook' '
 398        test_when_finished "rm -f .git/hooks/post-applypatch" &&
 399        rm -fr .git/rebase-apply &&
 400        git reset --hard &&
 401        git checkout first &&
 402        mkdir -p .git/hooks &&
 403        write_script .git/hooks/post-applypatch <<-\EOF &&
 404        git rev-parse HEAD >head.actual
 405        exit 1
 406        EOF
 407        git am patch1 &&
 408        test_path_is_missing .git/rebase-apply &&
 409        git diff --exit-code second &&
 410        test_cmp_rev second HEAD &&
 411        git rev-parse second >head.expected &&
 412        test_cmp head.expected head.actual
 413'
 414
 415test_expect_success 'am --scissors cuts the message at the scissors line' '
 416        rm -fr .git/rebase-apply &&
 417        git reset --hard &&
 418        git checkout second &&
 419        git am --scissors scissors-patch.eml &&
 420        test_path_is_missing .git/rebase-apply &&
 421        git diff --exit-code scissors &&
 422        test_cmp_rev scissors HEAD
 423'
 424
 425test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
 426        rm -fr .git/rebase-apply &&
 427        git reset --hard &&
 428        git checkout second &&
 429        test_config mailinfo.scissors true &&
 430        git am --no-scissors no-scissors-patch.eml &&
 431        test_path_is_missing .git/rebase-apply &&
 432        git diff --exit-code no-scissors &&
 433        test_cmp_rev no-scissors HEAD
 434'
 435
 436test_expect_success 'setup: new author and committer' '
 437        GIT_AUTHOR_NAME="Another Thor" &&
 438        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
 439        GIT_COMMITTER_NAME="Co M Miter" &&
 440        GIT_COMMITTER_EMAIL="c.miter@example.com" &&
 441        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 442'
 443
 444compare () {
 445        a=$(git cat-file commit "$2" | grep "^$1 ") &&
 446        b=$(git cat-file commit "$3" | grep "^$1 ") &&
 447        test "$a" = "$b"
 448}
 449
 450test_expect_success 'am changes committer and keeps author' '
 451        test_tick &&
 452        rm -fr .git/rebase-apply &&
 453        git reset --hard &&
 454        git checkout first &&
 455        git am patch2 &&
 456        test_path_is_missing .git/rebase-apply &&
 457        test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
 458        git diff --exit-code master..HEAD &&
 459        git diff --exit-code master^..HEAD^ &&
 460        compare author master HEAD &&
 461        compare author master^ HEAD^ &&
 462        test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
 463             "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
 464'
 465
 466test_expect_success 'am --signoff adds Signed-off-by: line' '
 467        rm -fr .git/rebase-apply &&
 468        git reset --hard &&
 469        git checkout -b master2 first &&
 470        git am --signoff <patch2 &&
 471        {
 472                printf "third\n\nSigned-off-by: %s <%s>\n\n" \
 473                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
 474                cat msg &&
 475                printf "Signed-off-by: %s <%s>\n\n" \
 476                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
 477        } >expected-log &&
 478        git log --pretty=%B -2 HEAD >actual &&
 479        test_cmp expected-log actual
 480'
 481
 482test_expect_success 'am stays in branch' '
 483        echo refs/heads/master2 >expected &&
 484        git symbolic-ref HEAD >actual &&
 485        test_cmp expected actual
 486'
 487
 488test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
 489        git format-patch --stdout first >patch3 &&
 490        git reset --hard first &&
 491        git am --signoff <patch3 &&
 492        git log --pretty=%B -2 HEAD >actual &&
 493        test_cmp expected-log actual
 494'
 495
 496test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
 497        NAME="A N Other" &&
 498        EMAIL="a.n.other@example.com" &&
 499        {
 500                printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
 501                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
 502                        "$NAME" "$EMAIL" &&
 503                cat msg &&
 504                printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
 505                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
 506                        "$NAME" "$EMAIL"
 507        } >expected-log &&
 508        git reset --hard first &&
 509        GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
 510                git am --signoff <patch3 &&
 511        git log --pretty=%B -2 HEAD >actual &&
 512        test_cmp expected-log actual
 513'
 514
 515test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
 516        NAME="A N Other" &&
 517        EMAIL="a.n.other@example.com" &&
 518        {
 519                printf "third\n\nSigned-off-by: %s <%s>\n\
 520Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
 521                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
 522                        "$NAME" "$EMAIL" \
 523                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
 524                cat msg &&
 525                printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
 526Signed-off-by: %s <%s>\n\n" \
 527                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
 528                        "$NAME" "$EMAIL" \
 529                        "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
 530        } >expected-log &&
 531        git format-patch --stdout first >patch3 &&
 532        git reset --hard first &&
 533        git am --signoff <patch3 &&
 534        git log --pretty=%B -2 HEAD >actual &&
 535        test_cmp expected-log actual
 536'
 537
 538test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
 539        git format-patch --stdout HEAD^ >tmp &&
 540        sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
 541        git reset --hard HEAD^ &&
 542        git am <patch4 &&
 543        git rev-parse HEAD >expected &&
 544        git rev-parse master2 >actual &&
 545        test_cmp expected actual
 546'
 547
 548test_expect_success 'am --keep really keeps the subject' '
 549        rm -fr .git/rebase-apply &&
 550        git reset --hard &&
 551        git checkout HEAD^ &&
 552        git am --keep patch4 &&
 553        test_path_is_missing .git/rebase-apply &&
 554        git cat-file commit HEAD >actual &&
 555        grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
 556'
 557
 558test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
 559        rm -fr .git/rebase-apply &&
 560        git reset --hard &&
 561        git checkout HEAD^ &&
 562        git am --keep-non-patch patch4 &&
 563        test_path_is_missing .git/rebase-apply &&
 564        git cat-file commit HEAD >actual &&
 565        grep "^\[foo\] third" actual
 566'
 567
 568test_expect_success 'setup am -3' '
 569        rm -fr .git/rebase-apply &&
 570        git reset --hard &&
 571        git checkout -b base3way master2 &&
 572        sed -n -e "3,\$p" msg >file &&
 573        head -n 9 msg >>file &&
 574        git add file &&
 575        test_tick &&
 576        git commit -m "copied stuff"
 577'
 578
 579test_expect_success 'am -3 falls back to 3-way merge' '
 580        rm -fr .git/rebase-apply &&
 581        git reset --hard &&
 582        git checkout -b lorem2 base3way &&
 583        git am -3 lorem-move.patch &&
 584        test_path_is_missing .git/rebase-apply &&
 585        git diff --exit-code lorem
 586'
 587
 588test_expect_success 'am -3 -p0 can read --no-prefix patch' '
 589        rm -fr .git/rebase-apply &&
 590        git reset --hard &&
 591        git checkout -b lorem3 base3way &&
 592        git am -3 -p0 lorem-zero.patch &&
 593        test_path_is_missing .git/rebase-apply &&
 594        git diff --exit-code lorem
 595'
 596
 597test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
 598        rm -fr .git/rebase-apply &&
 599        git reset --hard &&
 600        git checkout -b lorem4 base3way &&
 601        test_config am.threeWay 1 &&
 602        git am lorem-move.patch &&
 603        test_path_is_missing .git/rebase-apply &&
 604        git diff --exit-code lorem
 605'
 606
 607test_expect_success 'am with config am.threeWay overridden by --no-3way' '
 608        rm -fr .git/rebase-apply &&
 609        git reset --hard &&
 610        git checkout -b lorem5 base3way &&
 611        test_config am.threeWay 1 &&
 612        test_must_fail git am --no-3way lorem-move.patch &&
 613        test_path_is_dir .git/rebase-apply
 614'
 615
 616test_expect_success 'am can rename a file' '
 617        grep "^rename from" rename.patch &&
 618        rm -fr .git/rebase-apply &&
 619        git reset --hard &&
 620        git checkout lorem^0 &&
 621        git am rename.patch &&
 622        test_path_is_missing .git/rebase-apply &&
 623        git update-index --refresh &&
 624        git diff --exit-code rename
 625'
 626
 627test_expect_success 'am -3 can rename a file' '
 628        grep "^rename from" rename.patch &&
 629        rm -fr .git/rebase-apply &&
 630        git reset --hard &&
 631        git checkout lorem^0 &&
 632        git am -3 rename.patch &&
 633        test_path_is_missing .git/rebase-apply &&
 634        git update-index --refresh &&
 635        git diff --exit-code rename
 636'
 637
 638test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
 639        grep "^rename from" rename-add.patch &&
 640        rm -fr .git/rebase-apply &&
 641        git reset --hard &&
 642        git checkout lorem^0 &&
 643        git am -3 rename-add.patch &&
 644        test_path_is_missing .git/rebase-apply &&
 645        git update-index --refresh &&
 646        git diff --exit-code rename
 647'
 648
 649test_expect_success 'am -3 -q is quiet' '
 650        rm -fr .git/rebase-apply &&
 651        git checkout -f lorem2 &&
 652        git reset base3way --hard &&
 653        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 654        ! test -s output.out
 655'
 656
 657test_expect_success 'am pauses on conflict' '
 658        rm -fr .git/rebase-apply &&
 659        git reset --hard &&
 660        git checkout lorem2^^ &&
 661        test_must_fail git am lorem-move.patch &&
 662        test -d .git/rebase-apply
 663'
 664
 665test_expect_success 'am --show-current-patch' '
 666        git am --show-current-patch >actual.patch &&
 667        test_cmp .git/rebase-apply/0001 actual.patch
 668'
 669
 670test_expect_success 'am --skip works' '
 671        echo goodbye >expected &&
 672        git am --skip &&
 673        test_path_is_missing .git/rebase-apply &&
 674        git diff --exit-code lorem2^^ -- file &&
 675        test_cmp expected another
 676'
 677
 678test_expect_success 'am --abort removes a stray directory' '
 679        mkdir .git/rebase-apply &&
 680        git am --abort &&
 681        test_path_is_missing .git/rebase-apply
 682'
 683
 684test_expect_success 'am refuses patches when paused' '
 685        rm -fr .git/rebase-apply &&
 686        git reset --hard &&
 687        git checkout lorem2^^ &&
 688
 689        test_must_fail git am lorem-move.patch &&
 690        test_path_is_dir .git/rebase-apply &&
 691        test_cmp_rev lorem2^^ HEAD &&
 692
 693        test_must_fail git am <lorem-move.patch &&
 694        test_path_is_dir .git/rebase-apply &&
 695        test_cmp_rev lorem2^^ HEAD
 696'
 697
 698test_expect_success 'am --resolved works' '
 699        echo goodbye >expected &&
 700        rm -fr .git/rebase-apply &&
 701        git reset --hard &&
 702        git checkout lorem2^^ &&
 703        test_must_fail git am lorem-move.patch &&
 704        test -d .git/rebase-apply &&
 705        echo resolved >>file &&
 706        git add file &&
 707        git am --resolved &&
 708        test_path_is_missing .git/rebase-apply &&
 709        test_cmp expected another
 710'
 711
 712test_expect_success 'am --resolved fails if index has no changes' '
 713        rm -fr .git/rebase-apply &&
 714        git reset --hard &&
 715        git checkout lorem2^^ &&
 716        test_must_fail git am lorem-move.patch &&
 717        test_path_is_dir .git/rebase-apply &&
 718        test_cmp_rev lorem2^^ HEAD &&
 719        test_must_fail git am --resolved &&
 720        test_path_is_dir .git/rebase-apply &&
 721        test_cmp_rev lorem2^^ HEAD
 722'
 723
 724test_expect_success 'am --resolved fails if index has unmerged entries' '
 725        rm -fr .git/rebase-apply &&
 726        git reset --hard &&
 727        git checkout second &&
 728        test_must_fail git am -3 lorem-move.patch &&
 729        test_path_is_dir .git/rebase-apply &&
 730        test_cmp_rev second HEAD &&
 731        test_must_fail git am --resolved >err &&
 732        test_path_is_dir .git/rebase-apply &&
 733        test_cmp_rev second HEAD &&
 734        test_i18ngrep "still have unmerged paths" err
 735'
 736
 737test_expect_success 'am takes patches from a Pine mailbox' '
 738        rm -fr .git/rebase-apply &&
 739        git reset --hard &&
 740        git checkout first &&
 741        cat pine patch1 | git am &&
 742        test_path_is_missing .git/rebase-apply &&
 743        git diff --exit-code master^..HEAD
 744'
 745
 746test_expect_success 'am fails on mail without patch' '
 747        rm -fr .git/rebase-apply &&
 748        git reset --hard &&
 749        test_must_fail git am <failmail &&
 750        git am --abort &&
 751        test_path_is_missing .git/rebase-apply
 752'
 753
 754test_expect_success 'am fails on empty patch' '
 755        rm -fr .git/rebase-apply &&
 756        git reset --hard &&
 757        echo "---" >>failmail &&
 758        test_must_fail git am <failmail &&
 759        git am --skip &&
 760        test_path_is_missing .git/rebase-apply
 761'
 762
 763test_expect_success 'am works from stdin in subdirectory' '
 764        rm -fr subdir &&
 765        rm -fr .git/rebase-apply &&
 766        git reset --hard &&
 767        git checkout first &&
 768        (
 769                mkdir -p subdir &&
 770                cd subdir &&
 771                git am <../patch1
 772        ) &&
 773        git diff --exit-code second
 774'
 775
 776test_expect_success 'am works from file (relative path given) in subdirectory' '
 777        rm -fr subdir &&
 778        rm -fr .git/rebase-apply &&
 779        git reset --hard &&
 780        git checkout first &&
 781        (
 782                mkdir -p subdir &&
 783                cd subdir &&
 784                git am ../patch1
 785        ) &&
 786        git diff --exit-code second
 787'
 788
 789test_expect_success 'am works from file (absolute path given) in subdirectory' '
 790        rm -fr subdir &&
 791        rm -fr .git/rebase-apply &&
 792        git reset --hard &&
 793        git checkout first &&
 794        P=$(pwd) &&
 795        (
 796                mkdir -p subdir &&
 797                cd subdir &&
 798                git am "$P/patch1"
 799        ) &&
 800        git diff --exit-code second
 801'
 802
 803test_expect_success 'am --committer-date-is-author-date' '
 804        rm -fr .git/rebase-apply &&
 805        git reset --hard &&
 806        git checkout first &&
 807        test_tick &&
 808        git am --committer-date-is-author-date patch1 &&
 809        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 810        sed -ne "/^author /s/.*> //p" head1 >at &&
 811        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 812        test_cmp at ct
 813'
 814
 815test_expect_success 'am without --committer-date-is-author-date' '
 816        rm -fr .git/rebase-apply &&
 817        git reset --hard &&
 818        git checkout first &&
 819        test_tick &&
 820        git am patch1 &&
 821        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 822        sed -ne "/^author /s/.*> //p" head1 >at &&
 823        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 824        ! test_cmp at ct
 825'
 826
 827# This checks for +0000 because TZ is set to UTC and that should
 828# show up when the current time is used. The date in message is set
 829# by test_tick that uses -0700 timezone; if this feature does not
 830# work, we will see that instead of +0000.
 831test_expect_success 'am --ignore-date' '
 832        rm -fr .git/rebase-apply &&
 833        git reset --hard &&
 834        git checkout first &&
 835        test_tick &&
 836        git am --ignore-date patch1 &&
 837        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 838        sed -ne "/^author /s/.*> //p" head1 >at &&
 839        grep "+0000" at
 840'
 841
 842test_expect_success 'am into an unborn branch' '
 843        git rev-parse first^{tree} >expected &&
 844        rm -fr .git/rebase-apply &&
 845        git reset --hard &&
 846        rm -fr subdir &&
 847        mkdir subdir &&
 848        git format-patch --numbered-files -o subdir -1 first &&
 849        (
 850                cd subdir &&
 851                git init &&
 852                git am 1
 853        ) &&
 854        (
 855                cd subdir &&
 856                git rev-parse HEAD^{tree} >../actual
 857        ) &&
 858        test_cmp expected actual
 859'
 860
 861test_expect_success 'am newline in subject' '
 862        rm -fr .git/rebase-apply &&
 863        git reset --hard &&
 864        git checkout first &&
 865        test_tick &&
 866        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 867        git am <patchnl >output.out 2>&1 &&
 868        test_i18ngrep "^Applying: second \\\n foo$" output.out
 869'
 870
 871test_expect_success 'am -q is quiet' '
 872        rm -fr .git/rebase-apply &&
 873        git reset --hard &&
 874        git checkout first &&
 875        test_tick &&
 876        git am -q <patch1 >output.out 2>&1 &&
 877        ! test -s output.out
 878'
 879
 880test_expect_success 'am empty-file does not infloop' '
 881        rm -fr .git/rebase-apply &&
 882        git reset --hard &&
 883        touch empty-file &&
 884        test_tick &&
 885        test_must_fail git am empty-file 2>actual &&
 886        echo Patch format detection failed. >expected &&
 887        test_i18ncmp expected actual
 888'
 889
 890test_expect_success 'am --message-id really adds the message id' '
 891        rm -fr .git/rebase-apply &&
 892        git reset --hard &&
 893        git checkout HEAD^ &&
 894        git am --message-id patch1.eml &&
 895        test_path_is_missing .git/rebase-apply &&
 896        git cat-file commit HEAD | tail -n1 >actual &&
 897        grep Message-Id patch1.eml >expected &&
 898        test_cmp expected actual
 899'
 900
 901test_expect_success 'am.messageid really adds the message id' '
 902        rm -fr .git/rebase-apply &&
 903        git reset --hard &&
 904        git checkout HEAD^ &&
 905        test_config am.messageid true &&
 906        git am patch1.eml &&
 907        test_path_is_missing .git/rebase-apply &&
 908        git cat-file commit HEAD | tail -n1 >actual &&
 909        grep Message-Id patch1.eml >expected &&
 910        test_cmp expected actual
 911'
 912
 913test_expect_success 'am --message-id -s signs off after the message id' '
 914        rm -fr .git/rebase-apply &&
 915        git reset --hard &&
 916        git checkout HEAD^ &&
 917        git am -s --message-id patch1.eml &&
 918        test_path_is_missing .git/rebase-apply &&
 919        git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
 920        grep Message-Id patch1.eml >expected &&
 921        test_cmp expected actual
 922'
 923
 924test_expect_success 'am -3 works with rerere' '
 925        rm -fr .git/rebase-apply &&
 926        git reset --hard &&
 927
 928        # make patches one->two and two->three...
 929        test_commit one file &&
 930        test_commit two file &&
 931        test_commit three file &&
 932        git format-patch -2 --stdout >seq.patch &&
 933
 934        # and create a situation that conflicts...
 935        git reset --hard one &&
 936        test_commit other file &&
 937
 938        # enable rerere...
 939        test_config rerere.enabled true &&
 940        test_when_finished "rm -rf .git/rr-cache" &&
 941
 942        # ...and apply. Our resolution is to skip the first
 943        # patch, and the rerere the second one.
 944        test_must_fail git am -3 seq.patch &&
 945        test_must_fail git am --skip &&
 946        echo resolved >file &&
 947        git add file &&
 948        git am --resolved &&
 949
 950        # now apply again, and confirm that rerere engaged (we still
 951        # expect failure from am because rerere does not auto-commit
 952        # for us).
 953        git reset --hard other &&
 954        test_must_fail git am -3 seq.patch &&
 955        test_must_fail git am --skip &&
 956        echo resolved >expect &&
 957        test_cmp expect file
 958'
 959
 960test_expect_success 'am -s unexpected trailer block' '
 961        rm -fr .git/rebase-apply &&
 962        git reset --hard &&
 963        echo signed >file &&
 964        git add file &&
 965        cat >msg <<-EOF &&
 966        subject here
 967
 968        Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
 969        [jc: tweaked log message]
 970        Signed-off-by: J C H <j@c.h>
 971        EOF
 972        git commit -F msg &&
 973        git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
 974        git format-patch --stdout -1 >patch &&
 975
 976        git reset --hard HEAD^ &&
 977        git am -s patch &&
 978        (
 979                cat original &&
 980                echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
 981        ) >expect &&
 982        git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
 983        test_cmp expect actual &&
 984
 985        cat >msg <<-\EOF &&
 986        subject here
 987
 988        We make sure that there is a blank line between the log
 989        message proper and Signed-off-by: line added.
 990        EOF
 991        git reset HEAD^ &&
 992        git commit -F msg file &&
 993        git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
 994        git format-patch --stdout -1 >patch &&
 995
 996        git reset --hard HEAD^ &&
 997        git am -s patch &&
 998
 999        (
1000                cat original &&
1001                echo &&
1002                echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1003        ) >expect &&
1004        git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
1005        test_cmp expect actual
1006'
1007
1008test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1009        rm -fr .git/rebase-apply &&
1010        git checkout -f first &&
1011        echo mboxrd >>file &&
1012        git add file &&
1013        cat >msg <<-\INPUT_END &&
1014        mboxrd should escape the body
1015
1016        From could trip up a loose mbox parser
1017        >From extra escape for reversibility
1018        INPUT_END
1019        git commit -F msg &&
1020        git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
1021        grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1022        git checkout -f first &&
1023        git am --patch-format=mboxrd mboxrd1 &&
1024        git cat-file commit HEAD | tail -n4 >out &&
1025        test_cmp msg out
1026'
1027
1028test_expect_success 'am works with multi-line in-body headers' '
1029        FORTY="String that has a length of more than forty characters" &&
1030        LONG="$FORTY $FORTY" &&
1031        rm -fr .git/rebase-apply &&
1032        git checkout -f first &&
1033        echo one >> file &&
1034        git commit -am "$LONG
1035
1036    Body test" --author="$LONG <long@example.com>" &&
1037        git format-patch --stdout -1 >patch &&
1038        # bump from, date, and subject down to in-body header
1039        perl -lpe "
1040                if (/^From:/) {
1041                        print \"From: x <x\@example.com>\";
1042                        print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1043                        print \"Subject: x\n\";
1044                }
1045        " patch >msg &&
1046        git checkout HEAD^ &&
1047        git am msg &&
1048        # Ensure that the author and full message are present
1049        git cat-file commit HEAD | grep "^author.*long@example.com" &&
1050        git cat-file commit HEAD | grep "^$LONG$"
1051'
1052
1053test_expect_success 'am --quit keeps HEAD where it is' '
1054        mkdir .git/rebase-apply &&
1055        >.git/rebase-apply/last &&
1056        >.git/rebase-apply/next &&
1057        git rev-parse HEAD^ >.git/ORIG_HEAD &&
1058        git rev-parse HEAD >expected &&
1059        git am --quit &&
1060        test_path_is_missing .git/rebase-apply &&
1061        git rev-parse HEAD >actual &&
1062        test_cmp expected actual
1063'
1064
1065test_done