b50aad30d5ad8fb263a61a9f0b639a55ae2faaef
   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        sed -n -e "3,\$p" msg >file &&
 101        git add file &&
 102        test_tick &&
 103        git commit -m third &&
 104
 105        git format-patch --stdout first >patch2 &&
 106
 107        git checkout -b lorem &&
 108        sed -n -e "11,\$p" msg >file &&
 109        head -n 9 msg >>file &&
 110        test_tick &&
 111        git commit -a -m "moved stuff" &&
 112
 113        echo goodbye >another &&
 114        git add another &&
 115        test_tick &&
 116        git commit -m "added another file" &&
 117
 118        git format-patch --stdout master >lorem-move.patch &&
 119        # reset time
 120        unset test_tick &&
 121        test_tick
 122'
 123
 124test_expect_success 'am applies patch correctly' '
 125        git checkout first &&
 126        test_tick &&
 127        git am <patch1 &&
 128        ! test -d .git/rebase-apply &&
 129        git diff --exit-code second &&
 130        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 131        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 132'
 133
 134test_expect_success 'am applies patch e-mail not in a mbox' '
 135        git checkout first &&
 136        git am patch1.eml &&
 137        ! test -d .git/rebase-apply &&
 138        git diff --exit-code second &&
 139        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 140        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 141'
 142
 143test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
 144        git checkout first &&
 145        git am patch1-crlf.eml &&
 146        ! test -d .git/rebase-apply &&
 147        git diff --exit-code second &&
 148        test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
 149        test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
 150'
 151
 152test_expect_success 'setup: new author and committer' '
 153        GIT_AUTHOR_NAME="Another Thor" &&
 154        GIT_AUTHOR_EMAIL="a.thor@example.com" &&
 155        GIT_COMMITTER_NAME="Co M Miter" &&
 156        GIT_COMMITTER_EMAIL="c.miter@example.com" &&
 157        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 158'
 159
 160compare () {
 161        a=$(git cat-file commit "$2" | grep "^$1 ") &&
 162        b=$(git cat-file commit "$3" | grep "^$1 ") &&
 163        test "$a" = "$b"
 164}
 165
 166test_expect_success 'am changes committer and keeps author' '
 167        test_tick &&
 168        git checkout first &&
 169        git am patch2 &&
 170        ! test -d .git/rebase-apply &&
 171        test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
 172        git diff --exit-code master..HEAD &&
 173        git diff --exit-code master^..HEAD^ &&
 174        compare author master HEAD &&
 175        compare author master^ HEAD^ &&
 176        test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
 177             "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
 178'
 179
 180test_expect_success 'am --signoff adds Signed-off-by: line' '
 181        git checkout -b master2 first &&
 182        git am --signoff <patch2 &&
 183        printf "%s\n" "$signoff" >expected &&
 184        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
 185        git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
 186        test_cmp expected actual &&
 187        echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
 188        git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
 189        test_cmp expected actual
 190'
 191
 192test_expect_success 'am stays in branch' '
 193        echo refs/heads/master2 >expected &&
 194        git symbolic-ref HEAD >actual &&
 195        test_cmp expected actual
 196'
 197
 198test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
 199        git format-patch --stdout HEAD^ >patch3 &&
 200        sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4
 201        git checkout HEAD^ &&
 202        git am --signoff patch4 &&
 203        git cat-file commit HEAD >actual &&
 204        test $(grep -c "^Signed-off-by:" actual) -eq 1
 205'
 206
 207test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
 208        git rev-parse HEAD >expected &&
 209        git rev-parse master2 >actual &&
 210        test_cmp expected actual
 211'
 212
 213test_expect_success 'am --keep really keeps the subject' '
 214        git checkout HEAD^ &&
 215        git am --keep patch4 &&
 216        ! test -d .git/rebase-apply &&
 217        git cat-file commit HEAD >actual &&
 218        grep "Re: Re: Re: \[PATCH 1/5 v2\] third" actual
 219'
 220
 221test_expect_success 'am -3 falls back to 3-way merge' '
 222        git checkout -b lorem2 master2 &&
 223        sed -n -e "3,\$p" msg >file &&
 224        head -n 9 msg >>file &&
 225        git add file &&
 226        test_tick &&
 227        git commit -m "copied stuff" &&
 228        git am -3 lorem-move.patch &&
 229        ! test -d .git/rebase-apply &&
 230        git diff --exit-code lorem
 231'
 232
 233test_expect_success 'am -3 -q is quiet' '
 234        git reset master2 --hard &&
 235        sed -n -e "3,\$p" msg >file &&
 236        head -n 9 msg >>file &&
 237        git add file &&
 238        test_tick &&
 239        git commit -m "copied stuff" &&
 240        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 241        ! test -s output.out
 242'
 243
 244test_expect_success 'am pauses on conflict' '
 245        git checkout lorem2^^ &&
 246        test_must_fail git am lorem-move.patch &&
 247        test -d .git/rebase-apply
 248'
 249
 250test_expect_success 'am --skip works' '
 251        echo goodbye >expected &&
 252        git am --skip &&
 253        ! test -d .git/rebase-apply &&
 254        git diff --exit-code lorem2^^ -- file &&
 255        test_cmp expected another
 256'
 257
 258test_expect_success 'am --resolved works' '
 259        echo goodbye >expected &&
 260        git checkout lorem2^^ &&
 261        test_must_fail git am lorem-move.patch &&
 262        test -d .git/rebase-apply &&
 263        echo resolved >>file &&
 264        git add file &&
 265        git am --resolved &&
 266        ! test -d .git/rebase-apply &&
 267        test_cmp expected another
 268'
 269
 270test_expect_success 'am takes patches from a Pine mailbox' '
 271        git checkout first &&
 272        cat pine patch1 | git am &&
 273        ! test -d .git/rebase-apply &&
 274        git diff --exit-code master^..HEAD
 275'
 276
 277test_expect_success 'am fails on mail without patch' '
 278        test_must_fail git am <failmail &&
 279        rm -r .git/rebase-apply/
 280'
 281
 282test_expect_success 'am fails on empty patch' '
 283        echo "---" >>failmail &&
 284        test_must_fail git am <failmail &&
 285        git am --skip &&
 286        ! test -d .git/rebase-apply
 287'
 288
 289test_expect_success 'am works from stdin in subdirectory' '
 290        rm -fr subdir &&
 291        git checkout first &&
 292        (
 293                mkdir -p subdir &&
 294                cd subdir &&
 295                git am <../patch1
 296        ) &&
 297        git diff --exit-code second
 298'
 299
 300test_expect_success 'am works from file (relative path given) in subdirectory' '
 301        rm -fr subdir &&
 302        git checkout first &&
 303        (
 304                mkdir -p subdir &&
 305                cd subdir &&
 306                git am ../patch1
 307        ) &&
 308        git diff --exit-code second
 309'
 310
 311test_expect_success 'am works from file (absolute path given) in subdirectory' '
 312        rm -fr subdir &&
 313        git checkout first &&
 314        P=$(pwd) &&
 315        (
 316                mkdir -p subdir &&
 317                cd subdir &&
 318                git am "$P/patch1"
 319        ) &&
 320        git diff --exit-code second
 321'
 322
 323test_expect_success 'am --committer-date-is-author-date' '
 324        git checkout first &&
 325        test_tick &&
 326        git am --committer-date-is-author-date patch1 &&
 327        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 328        sed -ne "/^author /s/.*> //p" head1 >at &&
 329        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 330        test_cmp at ct
 331'
 332
 333test_expect_success 'am without --committer-date-is-author-date' '
 334        git checkout first &&
 335        test_tick &&
 336        git am patch1 &&
 337        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 338        sed -ne "/^author /s/.*> //p" head1 >at &&
 339        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 340        ! test_cmp at ct
 341'
 342
 343# This checks for +0000 because TZ is set to UTC and that should
 344# show up when the current time is used. The date in message is set
 345# by test_tick that uses -0700 timezone; if this feature does not
 346# work, we will see that instead of +0000.
 347test_expect_success 'am --ignore-date' '
 348        git checkout first &&
 349        test_tick &&
 350        git am --ignore-date patch1 &&
 351        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 352        sed -ne "/^author /s/.*> //p" head1 >at &&
 353        grep "+0000" at
 354'
 355
 356test_expect_success 'am into an unborn branch' '
 357        git rev-parse first^{tree} >expected &&
 358        rm -fr subdir &&
 359        mkdir subdir &&
 360        git format-patch --numbered-files -o subdir -1 first &&
 361        (
 362                cd subdir &&
 363                git init &&
 364                git am 1
 365        ) &&
 366        (
 367                cd subdir &&
 368                git rev-parse HEAD^{tree} >../actual
 369        ) &&
 370        test_cmp expected actual
 371'
 372
 373test_expect_success 'am newline in subject' '
 374        git checkout first &&
 375        test_tick &&
 376        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 377        git am <patchnl >output.out 2>&1 &&
 378        grep "^Applying: second \\\n foo$" output.out
 379'
 380
 381test_expect_success 'am -q is quiet' '
 382        git checkout first &&
 383        test_tick &&
 384        git am -q <patch1 >output.out 2>&1 &&
 385        ! test -s output.out
 386'
 387
 388test_done