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