t / t4150-am.shon commit verify_filename(): ask the caller to chose the kind of diagnosis (023e37c)
   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        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," 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\] third" actual
 263'
 264
 265test_expect_success 'am -3 falls back to 3-way merge' '
 266        rm -fr .git/rebase-apply &&
 267        git reset --hard &&
 268        git checkout -b lorem2 master2 &&
 269        sed -n -e "3,\$p" msg >file &&
 270        head -n 9 msg >>file &&
 271        git add file &&
 272        test_tick &&
 273        git commit -m "copied stuff" &&
 274        git am -3 lorem-move.patch &&
 275        ! test -d .git/rebase-apply &&
 276        git diff --exit-code lorem
 277'
 278
 279test_expect_success 'am can rename a file' '
 280        grep "^rename from" rename.patch &&
 281        rm -fr .git/rebase-apply &&
 282        git reset --hard &&
 283        git checkout lorem^0 &&
 284        git am rename.patch &&
 285        ! test -d .git/rebase-apply &&
 286        git update-index --refresh &&
 287        git diff --exit-code rename
 288'
 289
 290test_expect_success 'am -3 can rename a file' '
 291        grep "^rename from" rename.patch &&
 292        rm -fr .git/rebase-apply &&
 293        git reset --hard &&
 294        git checkout lorem^0 &&
 295        git am -3 rename.patch &&
 296        ! test -d .git/rebase-apply &&
 297        git update-index --refresh &&
 298        git diff --exit-code rename
 299'
 300
 301test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
 302        grep "^rename from" rename-add.patch &&
 303        rm -fr .git/rebase-apply &&
 304        git reset --hard &&
 305        git checkout lorem^0 &&
 306        git am -3 rename-add.patch &&
 307        ! test -d .git/rebase-apply &&
 308        git update-index --refresh &&
 309        git diff --exit-code rename
 310'
 311
 312test_expect_success 'am -3 -q is quiet' '
 313        rm -fr .git/rebase-apply &&
 314        git checkout -f lorem2 &&
 315        git reset master2 --hard &&
 316        sed -n -e "3,\$p" msg >file &&
 317        head -n 9 msg >>file &&
 318        git add file &&
 319        test_tick &&
 320        git commit -m "copied stuff" &&
 321        git am -3 -q lorem-move.patch >output.out 2>&1 &&
 322        ! test -s output.out
 323'
 324
 325test_expect_success 'am pauses on conflict' '
 326        rm -fr .git/rebase-apply &&
 327        git reset --hard &&
 328        git checkout lorem2^^ &&
 329        test_must_fail git am lorem-move.patch &&
 330        test -d .git/rebase-apply
 331'
 332
 333test_expect_success 'am --skip works' '
 334        echo goodbye >expected &&
 335        git am --skip &&
 336        ! test -d .git/rebase-apply &&
 337        git diff --exit-code lorem2^^ -- file &&
 338        test_cmp expected another
 339'
 340
 341test_expect_success 'am --resolved works' '
 342        echo goodbye >expected &&
 343        rm -fr .git/rebase-apply &&
 344        git reset --hard &&
 345        git checkout lorem2^^ &&
 346        test_must_fail git am lorem-move.patch &&
 347        test -d .git/rebase-apply &&
 348        echo resolved >>file &&
 349        git add file &&
 350        git am --resolved &&
 351        ! test -d .git/rebase-apply &&
 352        test_cmp expected another
 353'
 354
 355test_expect_success 'am takes patches from a Pine mailbox' '
 356        rm -fr .git/rebase-apply &&
 357        git reset --hard &&
 358        git checkout first &&
 359        cat pine patch1 | git am &&
 360        ! test -d .git/rebase-apply &&
 361        git diff --exit-code master^..HEAD
 362'
 363
 364test_expect_success 'am fails on mail without patch' '
 365        rm -fr .git/rebase-apply &&
 366        git reset --hard &&
 367        test_must_fail git am <failmail &&
 368        git am --abort &&
 369        ! test -d .git/rebase-apply
 370'
 371
 372test_expect_success 'am fails on empty patch' '
 373        rm -fr .git/rebase-apply &&
 374        git reset --hard &&
 375        echo "---" >>failmail &&
 376        test_must_fail git am <failmail &&
 377        git am --skip &&
 378        ! test -d .git/rebase-apply
 379'
 380
 381test_expect_success 'am works from stdin in subdirectory' '
 382        rm -fr subdir &&
 383        rm -fr .git/rebase-apply &&
 384        git reset --hard &&
 385        git checkout first &&
 386        (
 387                mkdir -p subdir &&
 388                cd subdir &&
 389                git am <../patch1
 390        ) &&
 391        git diff --exit-code second
 392'
 393
 394test_expect_success 'am works from file (relative path given) in subdirectory' '
 395        rm -fr subdir &&
 396        rm -fr .git/rebase-apply &&
 397        git reset --hard &&
 398        git checkout first &&
 399        (
 400                mkdir -p subdir &&
 401                cd subdir &&
 402                git am ../patch1
 403        ) &&
 404        git diff --exit-code second
 405'
 406
 407test_expect_success 'am works from file (absolute path given) in subdirectory' '
 408        rm -fr subdir &&
 409        rm -fr .git/rebase-apply &&
 410        git reset --hard &&
 411        git checkout first &&
 412        P=$(pwd) &&
 413        (
 414                mkdir -p subdir &&
 415                cd subdir &&
 416                git am "$P/patch1"
 417        ) &&
 418        git diff --exit-code second
 419'
 420
 421test_expect_success 'am --committer-date-is-author-date' '
 422        rm -fr .git/rebase-apply &&
 423        git reset --hard &&
 424        git checkout first &&
 425        test_tick &&
 426        git am --committer-date-is-author-date patch1 &&
 427        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 428        sed -ne "/^author /s/.*> //p" head1 >at &&
 429        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 430        test_cmp at ct
 431'
 432
 433test_expect_success 'am without --committer-date-is-author-date' '
 434        rm -fr .git/rebase-apply &&
 435        git reset --hard &&
 436        git checkout first &&
 437        test_tick &&
 438        git am patch1 &&
 439        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 440        sed -ne "/^author /s/.*> //p" head1 >at &&
 441        sed -ne "/^committer /s/.*> //p" head1 >ct &&
 442        ! test_cmp at ct
 443'
 444
 445# This checks for +0000 because TZ is set to UTC and that should
 446# show up when the current time is used. The date in message is set
 447# by test_tick that uses -0700 timezone; if this feature does not
 448# work, we will see that instead of +0000.
 449test_expect_success 'am --ignore-date' '
 450        rm -fr .git/rebase-apply &&
 451        git reset --hard &&
 452        git checkout first &&
 453        test_tick &&
 454        git am --ignore-date patch1 &&
 455        git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
 456        sed -ne "/^author /s/.*> //p" head1 >at &&
 457        grep "+0000" at
 458'
 459
 460test_expect_success 'am into an unborn branch' '
 461        git rev-parse first^{tree} >expected &&
 462        rm -fr .git/rebase-apply &&
 463        git reset --hard &&
 464        rm -fr subdir &&
 465        mkdir subdir &&
 466        git format-patch --numbered-files -o subdir -1 first &&
 467        (
 468                cd subdir &&
 469                git init &&
 470                git am 1
 471        ) &&
 472        (
 473                cd subdir &&
 474                git rev-parse HEAD^{tree} >../actual
 475        ) &&
 476        test_cmp expected actual
 477'
 478
 479test_expect_success 'am newline in subject' '
 480        rm -fr .git/rebase-apply &&
 481        git reset --hard &&
 482        git checkout first &&
 483        test_tick &&
 484        sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
 485        git am <patchnl >output.out 2>&1 &&
 486        test_i18ngrep "^Applying: second \\\n foo$" output.out
 487'
 488
 489test_expect_success 'am -q is quiet' '
 490        rm -fr .git/rebase-apply &&
 491        git reset --hard &&
 492        git checkout first &&
 493        test_tick &&
 494        git am -q <patch1 >output.out 2>&1 &&
 495        ! test -s output.out
 496'
 497
 498test_done