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