t / t4150-am.shon commit Merge branch 'tf/prompt-preserve-exit-status' (487b17d)
   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 'am -3 falls back to 3-way merge' '
 278        rm -fr .git/rebase-apply &&
 279        git reset --hard &&
 280        git checkout -b lorem2 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        git am -3 lorem-move.patch &&
 287        test_path_is_missing .git/rebase-apply &&
 288        git diff --exit-code lorem
 289'
 290
 291test_expect_success 'am -3 -p0 can read --no-prefix patch' '
 292        rm -fr .git/rebase-apply &&
 293        git reset --hard &&
 294        git checkout -b lorem3 master2 &&
 295        sed -n -e "3,\$p" msg >file &&
 296        head -n 9 msg >>file &&
 297        git add file &&
 298        test_tick &&
 299        git commit -m "copied stuff" &&
 300        git am -3 -p0 lorem-zero.patch &&
 301        test_path_is_missing .git/rebase-apply &&
 302        git diff --exit-code lorem
 303'
 304
 305test_expect_success 'am can rename a file' '
 306        grep "^rename from" rename.patch &&
 307        rm -fr .git/rebase-apply &&
 308        git reset --hard &&
 309        git checkout lorem^0 &&
 310        git am rename.patch &&
 311        test_path_is_missing .git/rebase-apply &&
 312        git update-index --refresh &&
 313        git diff --exit-code rename
 314'
 315
 316test_expect_success 'am -3 can rename a file' '
 317        grep "^rename from" rename.patch &&
 318        rm -fr .git/rebase-apply &&
 319        git reset --hard &&
 320        git checkout lorem^0 &&
 321        git am -3 rename.patch &&
 322        test_path_is_missing .git/rebase-apply &&
 323        git update-index --refresh &&
 324        git diff --exit-code rename
 325'
 326
 327test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
 328        grep "^rename from" rename-add.patch &&
 329        rm -fr .git/rebase-apply &&
 330        git reset --hard &&
 331        git checkout lorem^0 &&
 332        git am -3 rename-add.patch &&
 333        test_path_is_missing .git/rebase-apply &&
 334        git update-index --refresh &&
 335        git diff --exit-code rename
 336'
 337
 338test_expect_success 'am -3 -q is quiet' '
 339        rm -fr .git/rebase-apply &&
 340        git checkout -f lorem2 &&
 341        git reset master2 --hard &&
 342        sed -n -e "3,\$p" msg >file &&
 343        head -n 9 msg >>file &&
 344        git add file &&
 345        test_tick &&
 346        git commit -m "copied stuff" &&
 347        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 348        ! test -s output.out
 349'
 350
 351test_expect_success 'am pauses on conflict' '
 352        rm -fr .git/rebase-apply &&
 353        git reset --hard &&
 354        git checkout lorem2^^ &&
 355        test_must_fail git am lorem-move.patch &&
 356        test -d .git/rebase-apply
 357'
 358
 359test_expect_success 'am --skip works' '
 360        echo goodbye >expected &&
 361        git am --skip &&
 362        test_path_is_missing .git/rebase-apply &&
 363        git diff --exit-code lorem2^^ -- file &&
 364        test_cmp expected another
 365'
 366
 367test_expect_success 'am --abort removes a stray directory' '
 368        mkdir .git/rebase-apply &&
 369        git am --abort &&
 370        test_path_is_missing .git/rebase-apply
 371'
 372
 373test_expect_success 'am --resolved works' '
 374        echo goodbye >expected &&
 375        rm -fr .git/rebase-apply &&
 376        git reset --hard &&
 377        git checkout lorem2^^ &&
 378        test_must_fail git am lorem-move.patch &&
 379        test -d .git/rebase-apply &&
 380        echo resolved >>file &&
 381        git add file &&
 382        git am --resolved &&
 383        test_path_is_missing .git/rebase-apply &&
 384        test_cmp expected another
 385'
 386
 387test_expect_success 'am takes patches from a Pine mailbox' '
 388        rm -fr .git/rebase-apply &&
 389        git reset --hard &&
 390        git checkout first &&
 391        cat pine patch1 | git am &&
 392        test_path_is_missing .git/rebase-apply &&
 393        git diff --exit-code master^..HEAD
 394'
 395
 396test_expect_success 'am fails on mail without patch' '
 397        rm -fr .git/rebase-apply &&
 398        git reset --hard &&
 399        test_must_fail git am <failmail &&
 400        git am --abort &&
 401        test_path_is_missing .git/rebase-apply
 402'
 403
 404test_expect_success 'am fails on empty patch' '
 405        rm -fr .git/rebase-apply &&
 406        git reset --hard &&
 407        echo "---" >>failmail &&
 408        test_must_fail git am <failmail &&
 409        git am --skip &&
 410        test_path_is_missing .git/rebase-apply
 411'
 412
 413test_expect_success 'am works from stdin in subdirectory' '
 414        rm -fr subdir &&
 415        rm -fr .git/rebase-apply &&
 416        git reset --hard &&
 417        git checkout first &&
 418        (
 419                mkdir -p subdir &&
 420                cd subdir &&
 421                git am <../patch1
 422        ) &&
 423        git diff --exit-code second
 424'
 425
 426test_expect_success 'am works from file (relative path given) in subdirectory' '
 427        rm -fr subdir &&
 428        rm -fr .git/rebase-apply &&
 429        git reset --hard &&
 430        git checkout first &&
 431        (
 432                mkdir -p subdir &&
 433                cd subdir &&
 434                git am ../patch1
 435        ) &&
 436        git diff --exit-code second
 437'
 438
 439test_expect_success 'am works from file (absolute path given) in subdirectory' '
 440        rm -fr subdir &&
 441        rm -fr .git/rebase-apply &&
 442        git reset --hard &&
 443        git checkout first &&
 444        P=$(pwd) &&
 445        (
 446                mkdir -p subdir &&
 447                cd subdir &&
 448                git am "$P/patch1"
 449        ) &&
 450        git diff --exit-code second
 451'
 452
 453test_expect_success 'am --committer-date-is-author-date' '
 454        rm -fr .git/rebase-apply &&
 455        git reset --hard &&
 456        git checkout first &&
 457        test_tick &&
 458        git am --committer-date-is-author-date patch1 &&
 459        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 460        sed -ne "/^author /s/.*> //p" head1 >at &&
 461        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 462        test_cmp at ct
 463'
 464
 465test_expect_success 'am without --committer-date-is-author-date' '
 466        rm -fr .git/rebase-apply &&
 467        git reset --hard &&
 468        git checkout first &&
 469        test_tick &&
 470        git am patch1 &&
 471        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 472        sed -ne "/^author /s/.*> //p" head1 >at &&
 473        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 474        ! test_cmp at ct
 475'
 476
 477# This checks for +0000 because TZ is set to UTC and that should
 478# show up when the current time is used. The date in message is set
 479# by test_tick that uses -0700 timezone; if this feature does not
 480# work, we will see that instead of +0000.
 481test_expect_success 'am --ignore-date' '
 482        rm -fr .git/rebase-apply &&
 483        git reset --hard &&
 484        git checkout first &&
 485        test_tick &&
 486        git am --ignore-date patch1 &&
 487        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 488        sed -ne "/^author /s/.*> //p" head1 >at &&
 489        grep "+0000" at
 490'
 491
 492test_expect_success 'am into an unborn branch' '
 493        git rev-parse first^{tree} >expected &&
 494        rm -fr .git/rebase-apply &&
 495        git reset --hard &&
 496        rm -fr subdir &&
 497        mkdir subdir &&
 498        git format-patch --numbered-files -o subdir -1 first &&
 499        (
 500                cd subdir &&
 501                git init &&
 502                git am 1
 503        ) &&
 504        (
 505                cd subdir &&
 506                git rev-parse HEAD^{tree} >../actual
 507        ) &&
 508        test_cmp expected actual
 509'
 510
 511test_expect_success 'am newline in subject' '
 512        rm -fr .git/rebase-apply &&
 513        git reset --hard &&
 514        git checkout first &&
 515        test_tick &&
 516        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 517        git am <patchnl >output.out 2>&1 &&
 518        test_i18ngrep "^Applying: second \\\n foo$" output.out
 519'
 520
 521test_expect_success 'am -q is quiet' '
 522        rm -fr .git/rebase-apply &&
 523        git reset --hard &&
 524        git checkout first &&
 525        test_tick &&
 526        git am -q <patch1 >output.out 2>&1 &&
 527        ! test -s output.out
 528'
 529
 530test_expect_success 'am empty-file does not infloop' '
 531        rm -fr .git/rebase-apply &&
 532        git reset --hard &&
 533        touch empty-file &&
 534        test_tick &&
 535        test_must_fail git am empty-file 2>actual &&
 536        echo Patch format detection failed. >expected &&
 537        test_i18ncmp expected actual
 538'
 539
 540test_expect_success 'am --message-id really adds the message id' '
 541        rm -fr .git/rebase-apply &&
 542        git reset --hard &&
 543        git checkout HEAD^ &&
 544        git am --message-id patch1.eml &&
 545        test_path_is_missing .git/rebase-apply &&
 546        git cat-file commit HEAD | tail -n1 >actual &&
 547        grep Message-Id patch1.eml >expected &&
 548        test_cmp expected actual
 549'
 550
 551test_expect_success 'am --message-id -s signs off after the message id' '
 552        rm -fr .git/rebase-apply &&
 553        git reset --hard &&
 554        git checkout HEAD^ &&
 555        git am -s --message-id patch1.eml &&
 556        test_path_is_missing .git/rebase-apply &&
 557        git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
 558        grep Message-Id patch1.eml >expected &&
 559        test_cmp expected actual
 560'
 561
 562test_done