t / t4150-am.shon commit Sync with maint (6f5e880)
   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        q_to_tab <<-\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 "X-Fake-Field: Line One" &&
  89                echo "X-Fake-Field: Line Two" &&
  90                echo "X-Fake-Field: Line Three" &&
  91                git format-patch --stdout first | sed -e "1d"
  92        } > patch1.eml &&
  93        {
  94                echo "X-Fake-Field: Line One" &&
  95                echo "X-Fake-Field: Line Two" &&
  96                echo "X-Fake-Field: Line Three" &&
  97                git format-patch --stdout first | sed -e "1d"
  98        } | append_cr >patch1-crlf.eml &&
  99        {
 100                printf "%255s\\n" ""
 101                echo "X-Fake-Field: Line One" &&
 102                echo "X-Fake-Field: Line Two" &&
 103                echo "X-Fake-Field: Line Three" &&
 104                git format-patch --stdout first | sed -e "1d"
 105        } > patch1-ws.eml &&
 106
 107        sed -n -e "3,\$p" msg >file &&
 108        git add file &&
 109        test_tick &&
 110        git commit -m third &&
 111
 112        git format-patch --stdout first >patch2 &&
 113
 114        git checkout -b lorem &&
 115        sed -n -e "11,\$p" msg >file &&
 116        head -n 9 msg >>file &&
 117        test_tick &&
 118        git commit -a -m "moved stuff" &&
 119
 120        echo goodbye >another &&
 121        git add another &&
 122        test_tick &&
 123        git commit -m "added another file" &&
 124
 125        git format-patch --stdout master >lorem-move.patch &&
 126
 127        git checkout -b rename &&
 128        git mv file renamed &&
 129        git commit -m "renamed a file" &&
 130
 131        git format-patch -M --stdout lorem >rename.patch &&
 132
 133        git reset --soft lorem^ &&
 134        git commit -m "renamed a file and added another" &&
 135
 136        git format-patch -M --stdout lorem^ >rename-add.patch &&
 137
 138        # reset time
 139        sane_unset test_tick &&
 140        test_tick
 141'
 142
 143test_expect_success 'am applies patch correctly' '
 144        rm -fr .git/rebase-apply &&
 145        git reset --hard &&
 146        git checkout first &&
 147        test_tick &&
 148        git am <patch1 &&
 149        ! test -d .git/rebase-apply &&
 150        git diff --exit-code second &&
 151        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 152        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 153'
 154
 155test_expect_success 'am applies patch e-mail not in a mbox' '
 156        rm -fr .git/rebase-apply &&
 157        git reset --hard &&
 158        git checkout first &&
 159        git am patch1.eml &&
 160        ! test -d .git/rebase-apply &&
 161        git diff --exit-code second &&
 162        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 163        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 164'
 165
 166test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
 167        rm -fr .git/rebase-apply &&
 168        git reset --hard &&
 169        git checkout first &&
 170        git am patch1-crlf.eml &&
 171        ! test -d .git/rebase-apply &&
 172        git diff --exit-code second &&
 173        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 174        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 175'
 176
 177test_expect_success 'am applies patch e-mail with preceding whitespace' '
 178        rm -fr .git/rebase-apply &&
 179        git reset --hard &&
 180        git checkout first &&
 181        git am patch1-ws.eml &&
 182        ! test -d .git/rebase-apply &&
 183        git diff --exit-code second &&
 184        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 185        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 186'
 187
 188test_expect_success 'setup: new author and committer' '
 189        GIT_AUTHOR_NAME="Another Thor" &&
 190        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
 191        GIT_COMMITTER_NAME="Co M Miter" &&
 192        GIT_COMMITTER_EMAIL="c.miter@example.com" &&
 193        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 194'
 195
 196compare () {
 197        a=$(git cat-file commit "$2" | grep "^$1 ") &&
 198        b=$(git cat-file commit "$3" | grep "^$1 ") &&
 199        test "$a" = "$b"
 200}
 201
 202test_expect_success 'am changes committer and keeps author' '
 203        test_tick &&
 204        rm -fr .git/rebase-apply &&
 205        git reset --hard &&
 206        git checkout first &&
 207        git am patch2 &&
 208        ! test -d .git/rebase-apply &&
 209        test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
 210        git diff --exit-code master..HEAD &&
 211        git diff --exit-code master^..HEAD^ &&
 212        compare author master HEAD &&
 213        compare author master^ HEAD^ &&
 214        test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
 215             "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
 216'
 217
 218test_expect_success 'am --signoff adds Signed-off-by: line' '
 219        rm -fr .git/rebase-apply &&
 220        git reset --hard &&
 221        git checkout -b master2 first &&
 222        git am --signoff <patch2 &&
 223        printf "%s\n" "$signoff" >expected &&
 224        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
 225        git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
 226        test_cmp expected actual &&
 227        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
 228        git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
 229        test_cmp expected actual
 230'
 231
 232test_expect_success 'am stays in branch' '
 233        echo refs/heads/master2 >expected &&
 234        git symbolic-ref HEAD >actual &&
 235        test_cmp expected actual
 236'
 237
 238test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
 239        git format-patch --stdout HEAD^ >patch3 &&
 240        sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
 241        rm -fr .git/rebase-apply &&
 242        git reset --hard &&
 243        git checkout HEAD^ &&
 244        git am --signoff patch4 &&
 245        git cat-file commit HEAD >actual &&
 246        test $(grep -c "^Signed-off-by:" actual) -eq 1
 247'
 248
 249test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
 250        git rev-parse HEAD >expected &&
 251        git rev-parse master2 >actual &&
 252        test_cmp expected actual
 253'
 254
 255test_expect_success 'am --keep really keeps the subject' '
 256        rm -fr .git/rebase-apply &&
 257        git reset --hard &&
 258        git checkout HEAD^ &&
 259        git am --keep patch4 &&
 260        ! test -d .git/rebase-apply &&
 261        git cat-file commit HEAD >actual &&
 262        grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
 263'
 264
 265test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
 266        rm -fr .git/rebase-apply &&
 267        git reset --hard &&
 268        git checkout HEAD^ &&
 269        git am --keep-non-patch patch4 &&
 270        ! test -d .git/rebase-apply &&
 271        git cat-file commit HEAD >actual &&
 272        grep "^\[foo\] third" actual
 273'
 274
 275test_expect_success 'am -3 falls back to 3-way merge' '
 276        rm -fr .git/rebase-apply &&
 277        git reset --hard &&
 278        git checkout -b lorem2 master2 &&
 279        sed -n -e "3,\$p" msg >file &&
 280        head -n 9 msg >>file &&
 281        git add file &&
 282        test_tick &&
 283        git commit -m "copied stuff" &&
 284        git am -3 lorem-move.patch &&
 285        ! test -d .git/rebase-apply &&
 286        git diff --exit-code lorem
 287'
 288
 289test_expect_success 'am can rename a file' '
 290        grep "^rename from" rename.patch &&
 291        rm -fr .git/rebase-apply &&
 292        git reset --hard &&
 293        git checkout lorem^0 &&
 294        git am rename.patch &&
 295        ! test -d .git/rebase-apply &&
 296        git update-index --refresh &&
 297        git diff --exit-code rename
 298'
 299
 300test_expect_success 'am -3 can rename a file' '
 301        grep "^rename from" rename.patch &&
 302        rm -fr .git/rebase-apply &&
 303        git reset --hard &&
 304        git checkout lorem^0 &&
 305        git am -3 rename.patch &&
 306        ! test -d .git/rebase-apply &&
 307        git update-index --refresh &&
 308        git diff --exit-code rename
 309'
 310
 311test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
 312        grep "^rename from" rename-add.patch &&
 313        rm -fr .git/rebase-apply &&
 314        git reset --hard &&
 315        git checkout lorem^0 &&
 316        git am -3 rename-add.patch &&
 317        ! test -d .git/rebase-apply &&
 318        git update-index --refresh &&
 319        git diff --exit-code rename
 320'
 321
 322test_expect_success 'am -3 -q is quiet' '
 323        rm -fr .git/rebase-apply &&
 324        git checkout -f lorem2 &&
 325        git reset master2 --hard &&
 326        sed -n -e "3,\$p" msg >file &&
 327        head -n 9 msg >>file &&
 328        git add file &&
 329        test_tick &&
 330        git commit -m "copied stuff" &&
 331        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 332        ! test -s output.out
 333'
 334
 335test_expect_success 'am pauses on conflict' '
 336        rm -fr .git/rebase-apply &&
 337        git reset --hard &&
 338        git checkout lorem2^^ &&
 339        test_must_fail git am lorem-move.patch &&
 340        test -d .git/rebase-apply
 341'
 342
 343test_expect_success 'am --skip works' '
 344        echo goodbye >expected &&
 345        git am --skip &&
 346        ! test -d .git/rebase-apply &&
 347        git diff --exit-code lorem2^^ -- file &&
 348        test_cmp expected another
 349'
 350
 351test_expect_success 'am --resolved works' '
 352        echo goodbye >expected &&
 353        rm -fr .git/rebase-apply &&
 354        git reset --hard &&
 355        git checkout lorem2^^ &&
 356        test_must_fail git am lorem-move.patch &&
 357        test -d .git/rebase-apply &&
 358        echo resolved >>file &&
 359        git add file &&
 360        git am --resolved &&
 361        ! test -d .git/rebase-apply &&
 362        test_cmp expected another
 363'
 364
 365test_expect_success 'am takes patches from a Pine mailbox' '
 366        rm -fr .git/rebase-apply &&
 367        git reset --hard &&
 368        git checkout first &&
 369        cat pine patch1 | git am &&
 370        ! test -d .git/rebase-apply &&
 371        git diff --exit-code master^..HEAD
 372'
 373
 374test_expect_success 'am fails on mail without patch' '
 375        rm -fr .git/rebase-apply &&
 376        git reset --hard &&
 377        test_must_fail git am <failmail &&
 378        git am --abort &&
 379        ! test -d .git/rebase-apply
 380'
 381
 382test_expect_success 'am fails on empty patch' '
 383        rm -fr .git/rebase-apply &&
 384        git reset --hard &&
 385        echo "---" >>failmail &&
 386        test_must_fail git am <failmail &&
 387        git am --skip &&
 388        ! test -d .git/rebase-apply
 389'
 390
 391test_expect_success 'am works from stdin in subdirectory' '
 392        rm -fr subdir &&
 393        rm -fr .git/rebase-apply &&
 394        git reset --hard &&
 395        git checkout first &&
 396        (
 397                mkdir -p subdir &&
 398                cd subdir &&
 399                git am <../patch1
 400        ) &&
 401        git diff --exit-code second
 402'
 403
 404test_expect_success 'am works from file (relative path given) in subdirectory' '
 405        rm -fr subdir &&
 406        rm -fr .git/rebase-apply &&
 407        git reset --hard &&
 408        git checkout first &&
 409        (
 410                mkdir -p subdir &&
 411                cd subdir &&
 412                git am ../patch1
 413        ) &&
 414        git diff --exit-code second
 415'
 416
 417test_expect_success 'am works from file (absolute path given) in subdirectory' '
 418        rm -fr subdir &&
 419        rm -fr .git/rebase-apply &&
 420        git reset --hard &&
 421        git checkout first &&
 422        P=$(pwd) &&
 423        (
 424                mkdir -p subdir &&
 425                cd subdir &&
 426                git am "$P/patch1"
 427        ) &&
 428        git diff --exit-code second
 429'
 430
 431test_expect_success 'am --committer-date-is-author-date' '
 432        rm -fr .git/rebase-apply &&
 433        git reset --hard &&
 434        git checkout first &&
 435        test_tick &&
 436        git am --committer-date-is-author-date patch1 &&
 437        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 438        sed -ne "/^author /s/.*> //p" head1 >at &&
 439        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 440        test_cmp at ct
 441'
 442
 443test_expect_success 'am without --committer-date-is-author-date' '
 444        rm -fr .git/rebase-apply &&
 445        git reset --hard &&
 446        git checkout first &&
 447        test_tick &&
 448        git am patch1 &&
 449        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 450        sed -ne "/^author /s/.*> //p" head1 >at &&
 451        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 452        ! test_cmp at ct
 453'
 454
 455# This checks for +0000 because TZ is set to UTC and that should
 456# show up when the current time is used. The date in message is set
 457# by test_tick that uses -0700 timezone; if this feature does not
 458# work, we will see that instead of +0000.
 459test_expect_success 'am --ignore-date' '
 460        rm -fr .git/rebase-apply &&
 461        git reset --hard &&
 462        git checkout first &&
 463        test_tick &&
 464        git am --ignore-date patch1 &&
 465        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 466        sed -ne "/^author /s/.*> //p" head1 >at &&
 467        grep "+0000" at
 468'
 469
 470test_expect_success 'am into an unborn branch' '
 471        git rev-parse first^{tree} >expected &&
 472        rm -fr .git/rebase-apply &&
 473        git reset --hard &&
 474        rm -fr subdir &&
 475        mkdir subdir &&
 476        git format-patch --numbered-files -o subdir -1 first &&
 477        (
 478                cd subdir &&
 479                git init &&
 480                git am 1
 481        ) &&
 482        (
 483                cd subdir &&
 484                git rev-parse HEAD^{tree} >../actual
 485        ) &&
 486        test_cmp expected actual
 487'
 488
 489test_expect_success 'am newline in subject' '
 490        rm -fr .git/rebase-apply &&
 491        git reset --hard &&
 492        git checkout first &&
 493        test_tick &&
 494        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 495        git am <patchnl >output.out 2>&1 &&
 496        test_i18ngrep "^Applying: second \\\n foo$" output.out
 497'
 498
 499test_expect_success 'am -q is quiet' '
 500        rm -fr .git/rebase-apply &&
 501        git reset --hard &&
 502        git checkout first &&
 503        test_tick &&
 504        git am -q <patch1 >output.out 2>&1 &&
 505        ! test -s output.out
 506'
 507
 508test_done