t / t9001-send-email.shon commit git remote update: Fallback to remote if group does not exist (b344e16)
   1#!/bin/sh
   2
   3test_description='git send-email'
   4. ./test-lib.sh
   5
   6PROG='git send-email'
   7test_expect_success \
   8    'prepare reference tree' \
   9    'echo "1A quick brown fox jumps over the" >file &&
  10     echo "lazy dog" >>file &&
  11     git add file &&
  12     GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
  13
  14test_expect_success \
  15    'Setup helper tool' \
  16    '(echo "#!$SHELL_PATH"
  17      echo shift
  18      echo output=1
  19      echo "while test -f commandline\$output; do output=\$((\$output+1)); done"
  20      echo for a
  21      echo do
  22      echo "  echo \"!\$a!\""
  23      echo "done >commandline\$output"
  24      echo "cat > msgtxt\$output"
  25      ) >fake.sendmail &&
  26     chmod +x ./fake.sendmail &&
  27     git add fake.sendmail &&
  28     GIT_AUTHOR_NAME="A" git commit -a -m "Second."'
  29
  30clean_fake_sendmail() {
  31        rm -f commandline* msgtxt*
  32}
  33
  34test_expect_success 'Extract patches' '
  35    patches=`git format-patch -s --cc="One <one@example.com>" --cc=two@example.com -n HEAD^1`
  36'
  37
  38# Test no confirm early to ensure remaining tests will not hang
  39test_no_confirm () {
  40        rm -f no_confirm_okay
  41        echo n | \
  42                GIT_SEND_EMAIL_NOTTY=1 \
  43                git send-email \
  44                --from="Example <from@example.com>" \
  45                --to=nobody@example.com \
  46                --smtp-server="$(pwd)/fake.sendmail" \
  47                $@ \
  48                $patches > stdout &&
  49                test_must_fail grep "Send this email" stdout &&
  50                > no_confirm_okay
  51}
  52
  53# Exit immediately to prevent hang if a no-confirm test fails
  54check_no_confirm () {
  55        test -f no_confirm_okay || {
  56                say 'No confirm test failed; skipping remaining tests to prevent hanging'
  57                test_done
  58        }
  59}
  60
  61test_expect_success 'No confirm with --suppress-cc' '
  62        test_no_confirm --suppress-cc=sob
  63'
  64check_no_confirm
  65
  66test_expect_success 'No confirm with --confirm=never' '
  67        test_no_confirm --confirm=never
  68'
  69check_no_confirm
  70
  71# leave sendemail.confirm set to never after this so that none of the
  72# remaining tests prompt unintentionally.
  73test_expect_success 'No confirm with sendemail.confirm=never' '
  74        git config sendemail.confirm never &&
  75        test_no_confirm --compose --subject=foo
  76'
  77check_no_confirm
  78
  79test_expect_success 'Send patches' '
  80     git send-email --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
  81'
  82
  83cat >expected <<\EOF
  84!nobody@example.com!
  85!author@example.com!
  86!one@example.com!
  87!two@example.com!
  88EOF
  89test_expect_success \
  90    'Verify commandline' \
  91    'test_cmp expected commandline1'
  92
  93cat >expected-show-all-headers <<\EOF
  940001-Second.patch
  95(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
  96(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
  97(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
  98Dry-OK. Log says:
  99Server: relay.example.com
 100MAIL FROM:<from@example.com>
 101RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<bcc@example.com>
 102From: Example <from@example.com>
 103To: to@example.com
 104Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
 105Subject: [PATCH 1/1] Second.
 106Date: DATE-STRING
 107Message-Id: MESSAGE-ID-STRING
 108X-Mailer: X-MAILER-STRING
 109In-Reply-To: <unique-message-id@example.com>
 110References: <unique-message-id@example.com>
 111
 112Result: OK
 113EOF
 114
 115test_expect_success 'Show all headers' '
 116        git send-email \
 117                --dry-run \
 118                --suppress-cc=sob \
 119                --from="Example <from@example.com>" \
 120                --to=to@example.com \
 121                --cc=cc@example.com \
 122                --bcc=bcc@example.com \
 123                --in-reply-to="<unique-message-id@example.com>" \
 124                --smtp-server relay.example.com \
 125                $patches |
 126        sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
 127                -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
 128                -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
 129                >actual-show-all-headers &&
 130        test_cmp expected-show-all-headers actual-show-all-headers
 131'
 132
 133z8=zzzzzzzz
 134z64=$z8$z8$z8$z8$z8$z8$z8$z8
 135z512=$z64$z64$z64$z64$z64$z64$z64$z64
 136test_expect_success 'reject long lines' '
 137        clean_fake_sendmail &&
 138        cp $patches longline.patch &&
 139        echo $z512$z512 >>longline.patch &&
 140        test_must_fail git send-email \
 141                --from="Example <nobody@example.com>" \
 142                --to=nobody@example.com \
 143                --smtp-server="$(pwd)/fake.sendmail" \
 144                $patches longline.patch \
 145                2>errors &&
 146        grep longline.patch errors
 147'
 148
 149test_expect_success 'no patch was sent' '
 150        ! test -e commandline1
 151'
 152
 153test_expect_success 'Author From: in message body' '
 154        clean_fake_sendmail &&
 155        git send-email \
 156                --from="Example <nobody@example.com>" \
 157                --to=nobody@example.com \
 158                --smtp-server="$(pwd)/fake.sendmail" \
 159                $patches &&
 160        sed "1,/^$/d" < msgtxt1 > msgbody1
 161        grep "From: A <author@example.com>" msgbody1
 162'
 163
 164test_expect_success 'Author From: not in message body' '
 165        clean_fake_sendmail &&
 166        git send-email \
 167                --from="A <author@example.com>" \
 168                --to=nobody@example.com \
 169                --smtp-server="$(pwd)/fake.sendmail" \
 170                $patches &&
 171        sed "1,/^$/d" < msgtxt1 > msgbody1
 172        ! grep "From: A <author@example.com>" msgbody1
 173'
 174
 175test_expect_success 'allow long lines with --no-validate' '
 176        git send-email \
 177                --from="Example <nobody@example.com>" \
 178                --to=nobody@example.com \
 179                --smtp-server="$(pwd)/fake.sendmail" \
 180                --novalidate \
 181                $patches longline.patch \
 182                2>errors
 183'
 184
 185test_expect_success 'Invalid In-Reply-To' '
 186        clean_fake_sendmail &&
 187        git send-email \
 188                --from="Example <nobody@example.com>" \
 189                --to=nobody@example.com \
 190                --in-reply-to=" " \
 191                --smtp-server="$(pwd)/fake.sendmail" \
 192                $patches
 193                2>errors
 194        ! grep "^In-Reply-To: < *>" msgtxt1
 195'
 196
 197test_expect_success 'Valid In-Reply-To when prompting' '
 198        clean_fake_sendmail &&
 199        (echo "From Example <from@example.com>"
 200         echo "To Example <to@example.com>"
 201         echo ""
 202        ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \
 203                --smtp-server="$(pwd)/fake.sendmail" \
 204                $patches 2>errors &&
 205        ! grep "^In-Reply-To: < *>" msgtxt1
 206'
 207
 208test_expect_success 'setup fake editor' '
 209        (echo "#!$SHELL_PATH" &&
 210         echo "echo fake edit >>\"\$1\""
 211        ) >fake-editor &&
 212        chmod +x fake-editor
 213'
 214
 215test_set_editor "$(pwd)/fake-editor"
 216
 217test_expect_success '--compose works' '
 218        clean_fake_sendmail &&
 219        git send-email \
 220        --compose --subject foo \
 221        --from="Example <nobody@example.com>" \
 222        --to=nobody@example.com \
 223        --smtp-server="$(pwd)/fake.sendmail" \
 224        $patches \
 225        2>errors
 226'
 227
 228test_expect_success 'first message is compose text' '
 229        grep "^fake edit" msgtxt1
 230'
 231
 232test_expect_success 'second message is patch' '
 233        grep "Subject:.*Second" msgtxt2
 234'
 235
 236cat >expected-suppress-sob <<\EOF
 2370001-Second.patch
 238(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 239(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 240(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
 241Dry-OK. Log says:
 242Server: relay.example.com
 243MAIL FROM:<from@example.com>
 244RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
 245From: Example <from@example.com>
 246To: to@example.com
 247Cc: cc@example.com, A <author@example.com>, One <one@example.com>, two@example.com
 248Subject: [PATCH 1/1] Second.
 249Date: DATE-STRING
 250Message-Id: MESSAGE-ID-STRING
 251X-Mailer: X-MAILER-STRING
 252
 253Result: OK
 254EOF
 255
 256test_suppression () {
 257        git send-email \
 258                --dry-run \
 259                --suppress-cc=$1 \
 260                --from="Example <from@example.com>" \
 261                --to=to@example.com \
 262                --smtp-server relay.example.com \
 263                $patches |
 264        sed     -e "s/^\(Date:\).*/\1 DATE-STRING/" \
 265                -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
 266                -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
 267                >actual-suppress-$1 &&
 268        test_cmp expected-suppress-$1 actual-suppress-$1
 269}
 270
 271test_expect_success 'sendemail.cc set' '
 272        git config sendemail.cc cc@example.com &&
 273        test_suppression sob
 274'
 275
 276cat >expected-suppress-sob <<\EOF
 2770001-Second.patch
 278(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 279(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 280(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
 281Dry-OK. Log says:
 282Server: relay.example.com
 283MAIL FROM:<from@example.com>
 284RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
 285From: Example <from@example.com>
 286To: to@example.com
 287Cc: A <author@example.com>, One <one@example.com>, two@example.com
 288Subject: [PATCH 1/1] Second.
 289Date: DATE-STRING
 290Message-Id: MESSAGE-ID-STRING
 291X-Mailer: X-MAILER-STRING
 292
 293Result: OK
 294EOF
 295
 296test_expect_success 'sendemail.cc unset' '
 297        git config --unset sendemail.cc &&
 298        test_suppression sob
 299'
 300
 301cat >expected-suppress-all <<\EOF
 3020001-Second.patch
 303Dry-OK. Log says:
 304Server: relay.example.com
 305MAIL FROM:<from@example.com>
 306RCPT TO:<to@example.com>
 307From: Example <from@example.com>
 308To: to@example.com
 309Subject: [PATCH 1/1] Second.
 310Date: DATE-STRING
 311Message-Id: MESSAGE-ID-STRING
 312X-Mailer: X-MAILER-STRING
 313
 314Result: OK
 315EOF
 316
 317test_expect_success '--suppress-cc=all' '
 318        test_suppression all
 319'
 320
 321cat >expected-suppress-body <<\EOF
 3220001-Second.patch
 323(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 324(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 325(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
 326Dry-OK. Log says:
 327Server: relay.example.com
 328MAIL FROM:<from@example.com>
 329RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
 330From: Example <from@example.com>
 331To: to@example.com
 332Cc: A <author@example.com>, One <one@example.com>, two@example.com
 333Subject: [PATCH 1/1] Second.
 334Date: DATE-STRING
 335Message-Id: MESSAGE-ID-STRING
 336X-Mailer: X-MAILER-STRING
 337
 338Result: OK
 339EOF
 340
 341test_expect_success '--suppress-cc=body' '
 342        test_suppression body
 343'
 344
 345cat >expected-suppress-sob <<\EOF
 3460001-Second.patch
 347(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 348(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 349(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
 350Dry-OK. Log says:
 351Server: relay.example.com
 352MAIL FROM:<from@example.com>
 353RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
 354From: Example <from@example.com>
 355To: to@example.com
 356Cc: A <author@example.com>, One <one@example.com>, two@example.com
 357Subject: [PATCH 1/1] Second.
 358Date: DATE-STRING
 359Message-Id: MESSAGE-ID-STRING
 360X-Mailer: X-MAILER-STRING
 361
 362Result: OK
 363EOF
 364
 365test_expect_success '--suppress-cc=sob' '
 366        test_suppression sob
 367'
 368
 369cat >expected-suppress-bodycc <<\EOF
 3700001-Second.patch
 371(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 372(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
 373(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
 374(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
 375Dry-OK. Log says:
 376Server: relay.example.com
 377MAIL FROM:<from@example.com>
 378RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
 379From: Example <from@example.com>
 380To: to@example.com
 381Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
 382Subject: [PATCH 1/1] Second.
 383Date: DATE-STRING
 384Message-Id: MESSAGE-ID-STRING
 385X-Mailer: X-MAILER-STRING
 386
 387Result: OK
 388EOF
 389
 390test_expect_success '--suppress-cc=bodycc' '
 391        test_suppression bodycc
 392'
 393
 394cat >expected-suppress-cc <<\EOF
 3950001-Second.patch
 396(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
 397(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
 398Dry-OK. Log says:
 399Server: relay.example.com
 400MAIL FROM:<from@example.com>
 401RCPT TO:<to@example.com>,<author@example.com>,<committer@example.com>
 402From: Example <from@example.com>
 403To: to@example.com
 404Cc: A <author@example.com>, C O Mitter <committer@example.com>
 405Subject: [PATCH 1/1] Second.
 406Date: DATE-STRING
 407Message-Id: MESSAGE-ID-STRING
 408X-Mailer: X-MAILER-STRING
 409
 410Result: OK
 411EOF
 412
 413test_expect_success '--suppress-cc=cc' '
 414        test_suppression cc
 415'
 416
 417test_confirm () {
 418        echo y | \
 419                GIT_SEND_EMAIL_NOTTY=1 \
 420                git send-email \
 421                --from="Example <nobody@example.com>" \
 422                --to=nobody@example.com \
 423                --smtp-server="$(pwd)/fake.sendmail" \
 424                $@ $patches > stdout &&
 425        grep "Send this email" stdout
 426}
 427
 428test_expect_success '--confirm=always' '
 429        test_confirm --confirm=always --suppress-cc=all
 430'
 431
 432test_expect_success '--confirm=auto' '
 433        test_confirm --confirm=auto
 434'
 435
 436test_expect_success '--confirm=cc' '
 437        test_confirm --confirm=cc
 438'
 439
 440test_expect_success '--confirm=compose' '
 441        test_confirm --confirm=compose --compose
 442'
 443
 444test_expect_success 'confirm by default (due to cc)' '
 445        CONFIRM=$(git config --get sendemail.confirm) &&
 446        git config --unset sendemail.confirm &&
 447        test_confirm
 448        ret="$?"
 449        git config sendemail.confirm ${CONFIRM:-never}
 450        test $ret = "0"
 451'
 452
 453test_expect_success 'confirm by default (due to --compose)' '
 454        CONFIRM=$(git config --get sendemail.confirm) &&
 455        git config --unset sendemail.confirm &&
 456        test_confirm --suppress-cc=all --compose
 457        ret="$?"
 458        git config sendemail.confirm ${CONFIRM:-never}
 459        test $ret = "0"
 460'
 461
 462test_expect_success 'confirm detects EOF (inform assumes y)' '
 463        CONFIRM=$(git config --get sendemail.confirm) &&
 464        git config --unset sendemail.confirm &&
 465        rm -fr outdir &&
 466        git format-patch -2 -o outdir &&
 467        GIT_SEND_EMAIL_NOTTY=1 \
 468                git send-email \
 469                        --from="Example <nobody@example.com>" \
 470                        --to=nobody@example.com \
 471                        --smtp-server="$(pwd)/fake.sendmail" \
 472                        outdir/*.patch < /dev/null
 473        ret="$?"
 474        git config sendemail.confirm ${CONFIRM:-never}
 475        test $ret = "0"
 476'
 477
 478test_expect_success 'confirm detects EOF (auto causes failure)' '
 479        CONFIRM=$(git config --get sendemail.confirm) &&
 480        git config sendemail.confirm auto &&
 481        GIT_SEND_EMAIL_NOTTY=1 &&
 482        export GIT_SEND_EMAIL_NOTTY &&
 483                test_must_fail git send-email \
 484                        --from="Example <nobody@example.com>" \
 485                        --to=nobody@example.com \
 486                        --smtp-server="$(pwd)/fake.sendmail" \
 487                        $patches < /dev/null
 488        ret="$?"
 489        git config sendemail.confirm ${CONFIRM:-never}
 490        test $ret = "0"
 491'
 492
 493test_expect_success 'confirm doesnt loop forever' '
 494        CONFIRM=$(git config --get sendemail.confirm) &&
 495        git config sendemail.confirm auto &&
 496        GIT_SEND_EMAIL_NOTTY=1 &&
 497        export GIT_SEND_EMAIL_NOTTY &&
 498                yes "bogus" | test_must_fail git send-email \
 499                        --from="Example <nobody@example.com>" \
 500                        --to=nobody@example.com \
 501                        --smtp-server="$(pwd)/fake.sendmail" \
 502                        $patches
 503        ret="$?"
 504        git config sendemail.confirm ${CONFIRM:-never}
 505        test $ret = "0"
 506'
 507
 508test_expect_success 'utf8 Cc is rfc2047 encoded' '
 509        clean_fake_sendmail &&
 510        rm -fr outdir &&
 511        git format-patch -1 -o outdir --cc="àéìöú <utf8@example.com>" &&
 512        git send-email \
 513        --from="Example <nobody@example.com>" \
 514        --to=nobody@example.com \
 515        --smtp-server="$(pwd)/fake.sendmail" \
 516        outdir/*.patch &&
 517        grep "^Cc:" msgtxt1 |
 518        grep "=?utf-8?q?=C3=A0=C3=A9=C3=AC=C3=B6=C3=BA?= <utf8@example.com>"
 519'
 520
 521test_expect_success '--compose adds MIME for utf8 body' '
 522        clean_fake_sendmail &&
 523        (echo "#!$SHELL_PATH" &&
 524         echo "echo utf8 body: àéìöú >>\"\$1\""
 525        ) >fake-editor-utf8 &&
 526        chmod +x fake-editor-utf8 &&
 527          GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
 528          git send-email \
 529          --compose --subject foo \
 530          --from="Example <nobody@example.com>" \
 531          --to=nobody@example.com \
 532          --smtp-server="$(pwd)/fake.sendmail" \
 533          $patches &&
 534        grep "^utf8 body" msgtxt1 &&
 535        grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
 536'
 537
 538test_expect_success '--compose respects user mime type' '
 539        clean_fake_sendmail &&
 540        (echo "#!$SHELL_PATH" &&
 541         echo "(echo MIME-Version: 1.0"
 542         echo " echo Content-Type: text/plain\\; charset=iso-8859-1"
 543         echo " echo Content-Transfer-Encoding: 8bit"
 544         echo " echo Subject: foo"
 545         echo " echo "
 546         echo " echo utf8 body: àéìöú) >\"\$1\""
 547        ) >fake-editor-utf8-mime &&
 548        chmod +x fake-editor-utf8-mime &&
 549          GIT_EDITOR="\"$(pwd)/fake-editor-utf8-mime\"" \
 550          git send-email \
 551          --compose --subject foo \
 552          --from="Example <nobody@example.com>" \
 553          --to=nobody@example.com \
 554          --smtp-server="$(pwd)/fake.sendmail" \
 555          $patches &&
 556        grep "^utf8 body" msgtxt1 &&
 557        grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 &&
 558        ! grep "^Content-Type: text/plain; charset=utf-8" msgtxt1
 559'
 560
 561test_expect_success '--compose adds MIME for utf8 subject' '
 562        clean_fake_sendmail &&
 563          GIT_EDITOR="\"$(pwd)/fake-editor\"" \
 564          git send-email \
 565          --compose --subject utf8-sübjëct \
 566          --from="Example <nobody@example.com>" \
 567          --to=nobody@example.com \
 568          --smtp-server="$(pwd)/fake.sendmail" \
 569          $patches &&
 570        grep "^fake edit" msgtxt1 &&
 571        grep "^Subject: =?utf-8?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
 572'
 573
 574test_expect_success 'detects ambiguous reference/file conflict' '
 575        echo master > master &&
 576        git add master &&
 577        git commit -m"add master" &&
 578        test_must_fail git send-email --dry-run master 2>errors &&
 579        grep disambiguate errors
 580'
 581
 582test_expect_success 'feed two files' '
 583        rm -fr outdir &&
 584        git format-patch -2 -o outdir &&
 585        git send-email \
 586        --dry-run \
 587        --from="Example <nobody@example.com>" \
 588        --to=nobody@example.com \
 589        outdir/000?-*.patch 2>errors >out &&
 590        grep "^Subject: " out >subjects &&
 591        test "z$(sed -n -e 1p subjects)" = "zSubject: [PATCH 1/2] Second." &&
 592        test "z$(sed -n -e 2p subjects)" = "zSubject: [PATCH 2/2] add master"
 593'
 594
 595test_expect_success 'in-reply-to but no threading' '
 596        git send-email \
 597                --dry-run \
 598                --from="Example <nobody@example.com>" \
 599                --to=nobody@example.com \
 600                --in-reply-to="<in-reply-id@example.com>" \
 601                --no-thread \
 602                $patches |
 603        grep "In-Reply-To: <in-reply-id@example.com>"
 604'
 605
 606test_done