51962e481ea69e476776a15d7a651ed25ade5f01
   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 -ne "1p" msg &&
 109                echo &&
 110                echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
 111                echo "Date: $GIT_AUTHOR_DATE" &&
 112                echo &&
 113                sed -e "1,2d" msg &&
 114                echo &&
 115                echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
 116                echo "---" &&
 117                git diff-tree --no-commit-id --stat -p second
 118        } >patch1-stgit.eml &&
 119
 120        sed -n -e "3,\$p" msg >file &&
 121        git add file &&
 122        test_tick &&
 123        git commit -m third &&
 124
 125        git format-patch --stdout first >patch2 &&
 126
 127        git checkout -b lorem &&
 128        sed -n -e "11,\$p" msg >file &&
 129        head -n 9 msg >>file &&
 130        test_tick &&
 131        git commit -a -m "moved stuff" &&
 132
 133        echo goodbye >another &&
 134        git add another &&
 135        test_tick &&
 136        git commit -m "added another file" &&
 137
 138        git format-patch --stdout master >lorem-move.patch &&
 139        git format-patch --no-prefix --stdout master >lorem-zero.patch &&
 140
 141        git checkout -b rename &&
 142        git mv file renamed &&
 143        git commit -m "renamed a file" &&
 144
 145        git format-patch -M --stdout lorem >rename.patch &&
 146
 147        git reset --soft lorem^ &&
 148        git commit -m "renamed a file and added another" &&
 149
 150        git format-patch -M --stdout lorem^ >rename-add.patch &&
 151
 152        # reset time
 153        sane_unset test_tick &&
 154        test_tick
 155'
 156
 157test_expect_success 'am applies patch correctly' '
 158        rm -fr .git/rebase-apply &&
 159        git reset --hard &&
 160        git checkout first &&
 161        test_tick &&
 162        git am <patch1 &&
 163        test_path_is_missing .git/rebase-apply &&
 164        git diff --exit-code second &&
 165        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 166        test "$(git rev-parse second^)" = "$(git rev-parse 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 'am applies stgit patch' '
 203        rm -fr .git/rebase-apply &&
 204        git checkout -f first &&
 205        git am patch1-stgit.eml &&
 206        test_path_is_missing .git/rebase-apply &&
 207        git diff --exit-code second &&
 208        test_cmp_rev second HEAD &&
 209        test_cmp_rev second^ HEAD^
 210'
 211
 212test_expect_success 'am --patch-format=stgit applies stgit patch' '
 213        rm -fr .git/rebase-apply &&
 214        git checkout -f first &&
 215        git am --patch-format=stgit <patch1-stgit.eml &&
 216        test_path_is_missing .git/rebase-apply &&
 217        git diff --exit-code second &&
 218        test_cmp_rev second HEAD &&
 219        test_cmp_rev second^ HEAD^
 220'
 221
 222test_expect_success 'setup: new author and committer' '
 223        GIT_AUTHOR_NAME="Another Thor" &&
 224        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
 225        GIT_COMMITTER_NAME="Co M Miter" &&
 226        GIT_COMMITTER_EMAIL="c.miter@example.com" &&
 227        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 228'
 229
 230compare () {
 231        a=$(git cat-file commit "$2" | grep "^$1 ") &&
 232        b=$(git cat-file commit "$3" | grep "^$1 ") &&
 233        test "$a" = "$b"
 234}
 235
 236test_expect_success 'am changes committer and keeps author' '
 237        test_tick &&
 238        rm -fr .git/rebase-apply &&
 239        git reset --hard &&
 240        git checkout first &&
 241        git am patch2 &&
 242        test_path_is_missing .git/rebase-apply &&
 243        test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
 244        git diff --exit-code master..HEAD &&
 245        git diff --exit-code master^..HEAD^ &&
 246        compare author master HEAD &&
 247        compare author master^ HEAD^ &&
 248        test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
 249             "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
 250'
 251
 252test_expect_success 'am --signoff adds Signed-off-by: line' '
 253        rm -fr .git/rebase-apply &&
 254        git reset --hard &&
 255        git checkout -b master2 first &&
 256        git am --signoff <patch2 &&
 257        printf "%s\n" "$signoff" >expected &&
 258        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
 259        git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
 260        test_cmp expected actual &&
 261        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
 262        git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
 263        test_cmp expected actual
 264'
 265
 266test_expect_success 'am stays in branch' '
 267        echo refs/heads/master2 >expected &&
 268        git symbolic-ref HEAD >actual &&
 269        test_cmp expected actual
 270'
 271
 272test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
 273        git format-patch --stdout HEAD^ >patch3 &&
 274        sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
 275        rm -fr .git/rebase-apply &&
 276        git reset --hard &&
 277        git checkout HEAD^ &&
 278        git am --signoff patch4 &&
 279        git cat-file commit HEAD >actual &&
 280        test $(grep -c "^Signed-off-by:" actual) -eq 1
 281'
 282
 283test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
 284        git rev-parse HEAD >expected &&
 285        git rev-parse master2 >actual &&
 286        test_cmp expected actual
 287'
 288
 289test_expect_success 'am --keep really keeps the subject' '
 290        rm -fr .git/rebase-apply &&
 291        git reset --hard &&
 292        git checkout HEAD^ &&
 293        git am --keep patch4 &&
 294        test_path_is_missing .git/rebase-apply &&
 295        git cat-file commit HEAD >actual &&
 296        grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
 297'
 298
 299test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
 300        rm -fr .git/rebase-apply &&
 301        git reset --hard &&
 302        git checkout HEAD^ &&
 303        git am --keep-non-patch patch4 &&
 304        test_path_is_missing .git/rebase-apply &&
 305        git cat-file commit HEAD >actual &&
 306        grep "^\[foo\] third" actual
 307'
 308
 309test_expect_success 'am -3 falls back to 3-way merge' '
 310        rm -fr .git/rebase-apply &&
 311        git reset --hard &&
 312        git checkout -b lorem2 master2 &&
 313        sed -n -e "3,\$p" msg >file &&
 314        head -n 9 msg >>file &&
 315        git add file &&
 316        test_tick &&
 317        git commit -m "copied stuff" &&
 318        git am -3 lorem-move.patch &&
 319        test_path_is_missing .git/rebase-apply &&
 320        git diff --exit-code lorem
 321'
 322
 323test_expect_success 'am -3 -p0 can read --no-prefix patch' '
 324        rm -fr .git/rebase-apply &&
 325        git reset --hard &&
 326        git checkout -b lorem3 master2 &&
 327        sed -n -e "3,\$p" msg >file &&
 328        head -n 9 msg >>file &&
 329        git add file &&
 330        test_tick &&
 331        git commit -m "copied stuff" &&
 332        git am -3 -p0 lorem-zero.patch &&
 333        test_path_is_missing .git/rebase-apply &&
 334        git diff --exit-code lorem
 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 master2 --hard &&
 374        sed -n -e "3,\$p" msg >file &&
 375        head -n 9 msg >>file &&
 376        git add file &&
 377        test_tick &&
 378        git commit -m "copied stuff" &&
 379        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 380        ! test -s output.out
 381'
 382
 383test_expect_success 'am pauses on conflict' '
 384        rm -fr .git/rebase-apply &&
 385        git reset --hard &&
 386        git checkout lorem2^^ &&
 387        test_must_fail git am lorem-move.patch &&
 388        test -d .git/rebase-apply
 389'
 390
 391test_expect_success 'am --skip works' '
 392        echo goodbye >expected &&
 393        git am --skip &&
 394        test_path_is_missing .git/rebase-apply &&
 395        git diff --exit-code lorem2^^ -- file &&
 396        test_cmp expected another
 397'
 398
 399test_expect_success 'am --abort removes a stray directory' '
 400        mkdir .git/rebase-apply &&
 401        git am --abort &&
 402        test_path_is_missing .git/rebase-apply
 403'
 404
 405test_expect_success 'am --resolved works' '
 406        echo goodbye >expected &&
 407        rm -fr .git/rebase-apply &&
 408        git reset --hard &&
 409        git checkout lorem2^^ &&
 410        test_must_fail git am lorem-move.patch &&
 411        test -d .git/rebase-apply &&
 412        echo resolved >>file &&
 413        git add file &&
 414        git am --resolved &&
 415        test_path_is_missing .git/rebase-apply &&
 416        test_cmp expected another
 417'
 418
 419test_expect_success 'am takes patches from a Pine mailbox' '
 420        rm -fr .git/rebase-apply &&
 421        git reset --hard &&
 422        git checkout first &&
 423        cat pine patch1 | git am &&
 424        test_path_is_missing .git/rebase-apply &&
 425        git diff --exit-code master^..HEAD
 426'
 427
 428test_expect_success 'am fails on mail without patch' '
 429        rm -fr .git/rebase-apply &&
 430        git reset --hard &&
 431        test_must_fail git am <failmail &&
 432        git am --abort &&
 433        test_path_is_missing .git/rebase-apply
 434'
 435
 436test_expect_success 'am fails on empty patch' '
 437        rm -fr .git/rebase-apply &&
 438        git reset --hard &&
 439        echo "---" >>failmail &&
 440        test_must_fail git am <failmail &&
 441        git am --skip &&
 442        test_path_is_missing .git/rebase-apply
 443'
 444
 445test_expect_success 'am works from stdin in subdirectory' '
 446        rm -fr subdir &&
 447        rm -fr .git/rebase-apply &&
 448        git reset --hard &&
 449        git checkout first &&
 450        (
 451                mkdir -p subdir &&
 452                cd subdir &&
 453                git am <../patch1
 454        ) &&
 455        git diff --exit-code second
 456'
 457
 458test_expect_success 'am works from file (relative path given) in subdirectory' '
 459        rm -fr subdir &&
 460        rm -fr .git/rebase-apply &&
 461        git reset --hard &&
 462        git checkout first &&
 463        (
 464                mkdir -p subdir &&
 465                cd subdir &&
 466                git am ../patch1
 467        ) &&
 468        git diff --exit-code second
 469'
 470
 471test_expect_success 'am works from file (absolute path given) in subdirectory' '
 472        rm -fr subdir &&
 473        rm -fr .git/rebase-apply &&
 474        git reset --hard &&
 475        git checkout first &&
 476        P=$(pwd) &&
 477        (
 478                mkdir -p subdir &&
 479                cd subdir &&
 480                git am "$P/patch1"
 481        ) &&
 482        git diff --exit-code second
 483'
 484
 485test_expect_success 'am --committer-date-is-author-date' '
 486        rm -fr .git/rebase-apply &&
 487        git reset --hard &&
 488        git checkout first &&
 489        test_tick &&
 490        git am --committer-date-is-author-date patch1 &&
 491        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 492        sed -ne "/^author /s/.*> //p" head1 >at &&
 493        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 494        test_cmp at ct
 495'
 496
 497test_expect_success 'am without --committer-date-is-author-date' '
 498        rm -fr .git/rebase-apply &&
 499        git reset --hard &&
 500        git checkout first &&
 501        test_tick &&
 502        git am patch1 &&
 503        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 504        sed -ne "/^author /s/.*> //p" head1 >at &&
 505        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 506        ! test_cmp at ct
 507'
 508
 509# This checks for +0000 because TZ is set to UTC and that should
 510# show up when the current time is used. The date in message is set
 511# by test_tick that uses -0700 timezone; if this feature does not
 512# work, we will see that instead of +0000.
 513test_expect_success 'am --ignore-date' '
 514        rm -fr .git/rebase-apply &&
 515        git reset --hard &&
 516        git checkout first &&
 517        test_tick &&
 518        git am --ignore-date patch1 &&
 519        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 520        sed -ne "/^author /s/.*> //p" head1 >at &&
 521        grep "+0000" at
 522'
 523
 524test_expect_success 'am into an unborn branch' '
 525        git rev-parse first^{tree} >expected &&
 526        rm -fr .git/rebase-apply &&
 527        git reset --hard &&
 528        rm -fr subdir &&
 529        mkdir subdir &&
 530        git format-patch --numbered-files -o subdir -1 first &&
 531        (
 532                cd subdir &&
 533                git init &&
 534                git am 1
 535        ) &&
 536        (
 537                cd subdir &&
 538                git rev-parse HEAD^{tree} >../actual
 539        ) &&
 540        test_cmp expected actual
 541'
 542
 543test_expect_success 'am newline in subject' '
 544        rm -fr .git/rebase-apply &&
 545        git reset --hard &&
 546        git checkout first &&
 547        test_tick &&
 548        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 549        git am <patchnl >output.out 2>&1 &&
 550        test_i18ngrep "^Applying: second \\\n foo$" output.out
 551'
 552
 553test_expect_success 'am -q is quiet' '
 554        rm -fr .git/rebase-apply &&
 555        git reset --hard &&
 556        git checkout first &&
 557        test_tick &&
 558        git am -q <patch1 >output.out 2>&1 &&
 559        ! test -s output.out
 560'
 561
 562test_expect_success 'am empty-file does not infloop' '
 563        rm -fr .git/rebase-apply &&
 564        git reset --hard &&
 565        touch empty-file &&
 566        test_tick &&
 567        test_must_fail git am empty-file 2>actual &&
 568        echo Patch format detection failed. >expected &&
 569        test_i18ncmp expected actual
 570'
 571
 572test_expect_success 'am --message-id really adds the message id' '
 573        rm -fr .git/rebase-apply &&
 574        git reset --hard &&
 575        git checkout HEAD^ &&
 576        git am --message-id patch1.eml &&
 577        test_path_is_missing .git/rebase-apply &&
 578        git cat-file commit HEAD | tail -n1 >actual &&
 579        grep Message-Id patch1.eml >expected &&
 580        test_cmp expected actual
 581'
 582
 583test_expect_success 'am --message-id -s signs off after the message id' '
 584        rm -fr .git/rebase-apply &&
 585        git reset --hard &&
 586        git checkout HEAD^ &&
 587        git am -s --message-id patch1.eml &&
 588        test_path_is_missing .git/rebase-apply &&
 589        git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
 590        grep Message-Id patch1.eml >expected &&
 591        test_cmp expected actual
 592'
 593
 594test_done