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