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