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