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