t / t4014-format-patch.shon commit format-patch --notes: show notes after three-dashes (bd1470b)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Junio C Hamano
   4#
   5
   6test_description='various format-patch tests'
   7
   8. ./test-lib.sh
   9. "$TEST_DIRECTORY"/lib-terminal.sh
  10
  11test_expect_success setup '
  12
  13        for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
  14        cat file >elif &&
  15        git add file elif &&
  16        test_tick &&
  17        git commit -m Initial &&
  18        git checkout -b side &&
  19
  20        for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
  21        test_chmod +x elif &&
  22        test_tick &&
  23        git commit -m "Side changes #1" &&
  24
  25        for i in D E F; do echo "$i"; done >>file &&
  26        git update-index file &&
  27        test_tick &&
  28        git commit -m "Side changes #2" &&
  29        git tag C2 &&
  30
  31        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
  32        git update-index file &&
  33        test_tick &&
  34        git commit -m "Side changes #3 with \\n backslash-n in it." &&
  35
  36        git checkout master &&
  37        git diff-tree -p C2 | git apply --index &&
  38        test_tick &&
  39        git commit -m "Master accepts moral equivalent of #2"
  40
  41'
  42
  43test_expect_success "format-patch --ignore-if-in-upstream" '
  44
  45        git format-patch --stdout master..side >patch0 &&
  46        cnt=`grep "^From " patch0 | wc -l` &&
  47        test $cnt = 3
  48
  49'
  50
  51test_expect_success "format-patch --ignore-if-in-upstream" '
  52
  53        git format-patch --stdout \
  54                --ignore-if-in-upstream master..side >patch1 &&
  55        cnt=`grep "^From " patch1 | wc -l` &&
  56        test $cnt = 2
  57
  58'
  59
  60test_expect_success "format-patch doesn't consider merge commits" '
  61
  62        git checkout -b slave master &&
  63        echo "Another line" >>file &&
  64        test_tick &&
  65        git commit -am "Slave change #1" &&
  66        echo "Yet another line" >>file &&
  67        test_tick &&
  68        git commit -am "Slave change #2" &&
  69        git checkout -b merger master &&
  70        test_tick &&
  71        git merge --no-ff slave &&
  72        cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
  73        test $cnt = 3
  74'
  75
  76test_expect_success "format-patch result applies" '
  77
  78        git checkout -b rebuild-0 master &&
  79        git am -3 patch0 &&
  80        cnt=`git rev-list master.. | wc -l` &&
  81        test $cnt = 2
  82'
  83
  84test_expect_success "format-patch --ignore-if-in-upstream result applies" '
  85
  86        git checkout -b rebuild-1 master &&
  87        git am -3 patch1 &&
  88        cnt=`git rev-list master.. | wc -l` &&
  89        test $cnt = 2
  90'
  91
  92test_expect_success 'commit did not screw up the log message' '
  93
  94        git cat-file commit side | grep "^Side .* with .* backslash-n"
  95
  96'
  97
  98test_expect_success 'format-patch did not screw up the log message' '
  99
 100        grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
 101        grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
 102
 103'
 104
 105test_expect_success 'replay did not screw up the log message' '
 106
 107        git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
 108
 109'
 110
 111test_expect_success 'extra headers' '
 112
 113        git config format.headers "To: R. E. Cipient <rcipient@example.com>
 114" &&
 115        git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
 116" &&
 117        git format-patch --stdout master..side > patch2 &&
 118        sed -e "/^\$/q" patch2 > hdrs2 &&
 119        grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
 120        grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
 121
 122'
 123
 124test_expect_success 'extra headers without newlines' '
 125
 126        git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
 127        git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
 128        git format-patch --stdout master..side >patch3 &&
 129        sed -e "/^\$/q" patch3 > hdrs3 &&
 130        grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
 131        grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
 132
 133'
 134
 135test_expect_success 'extra headers with multiple To:s' '
 136
 137        git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
 138        git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
 139        git format-patch --stdout master..side > patch4 &&
 140        sed -e "/^\$/q" patch4 > hdrs4 &&
 141        grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
 142        grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
 143'
 144
 145test_expect_success 'additional command line cc' '
 146
 147        git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
 148        git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
 149        grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
 150        grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
 151'
 152
 153test_expect_success 'command line headers' '
 154
 155        git config --unset-all format.headers &&
 156        git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
 157        grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
 158'
 159
 160test_expect_success 'configuration headers and command line headers' '
 161
 162        git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
 163        git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
 164        grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
 165        grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
 166'
 167
 168test_expect_success 'command line To: header' '
 169
 170        git config --unset-all format.headers &&
 171        git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
 172        grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
 173'
 174
 175test_expect_success 'configuration To: header' '
 176
 177        git config format.to "R. E. Cipient <rcipient@example.com>" &&
 178        git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
 179        grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
 180'
 181
 182# check_patch <patch>: Verify that <patch> looks like a half-sane
 183# patch email to avoid a false positive with !grep
 184check_patch () {
 185        grep -e "^From:" "$1" &&
 186        grep -e "^Date:" "$1" &&
 187        grep -e "^Subject:" "$1"
 188}
 189
 190test_expect_success '--no-to overrides config.to' '
 191
 192        git config --replace-all format.to \
 193                "R. E. Cipient <rcipient@example.com>" &&
 194        git format-patch --no-to --stdout master..side |
 195        sed -e "/^\$/q" >patch10 &&
 196        check_patch patch10 &&
 197        ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
 198'
 199
 200test_expect_success '--no-to and --to replaces config.to' '
 201
 202        git config --replace-all format.to \
 203                "Someone <someone@out.there>" &&
 204        git format-patch --no-to --to="Someone Else <else@out.there>" \
 205                --stdout master..side |
 206        sed -e "/^\$/q" >patch11 &&
 207        check_patch patch11 &&
 208        ! grep "^To: Someone <someone@out.there>\$" patch11 &&
 209        grep "^To: Someone Else <else@out.there>\$" patch11
 210'
 211
 212test_expect_success '--no-cc overrides config.cc' '
 213
 214        git config --replace-all format.cc \
 215                "C. E. Cipient <rcipient@example.com>" &&
 216        git format-patch --no-cc --stdout master..side |
 217        sed -e "/^\$/q" >patch12 &&
 218        check_patch patch12 &&
 219        ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
 220'
 221
 222test_expect_success '--no-add-header overrides config.headers' '
 223
 224        git config --replace-all format.headers \
 225                "Header1: B. E. Cipient <rcipient@example.com>" &&
 226        git format-patch --no-add-header --stdout master..side |
 227        sed -e "/^\$/q" >patch13 &&
 228        check_patch patch13 &&
 229        ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
 230'
 231
 232test_expect_success 'multiple files' '
 233
 234        rm -rf patches/ &&
 235        git checkout side &&
 236        git format-patch -o patches/ master &&
 237        ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
 238'
 239
 240check_threading () {
 241        expect="$1" &&
 242        shift &&
 243        (git format-patch --stdout "$@"; echo $? > status.out) |
 244        # Prints everything between the Message-ID and In-Reply-To,
 245        # and replaces all Message-ID-lookalikes by a sequence number
 246        "$PERL_PATH" -ne '
 247                if (/^(message-id|references|in-reply-to)/i) {
 248                        $printing = 1;
 249                } elsif (/^\S/) {
 250                        $printing = 0;
 251                }
 252                if ($printing) {
 253                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 254                        for $k (keys %h) {s/$k/$h{$k}/};
 255                        print;
 256                }
 257                print "---\n" if /^From /i;
 258        ' > actual &&
 259        test 0 = "$(cat status.out)" &&
 260        test_cmp "$expect" actual
 261}
 262
 263cat >> expect.no-threading <<EOF
 264---
 265---
 266---
 267EOF
 268
 269test_expect_success 'no threading' '
 270        git checkout side &&
 271        check_threading expect.no-threading master
 272'
 273
 274cat > expect.thread <<EOF
 275---
 276Message-Id: <0>
 277---
 278Message-Id: <1>
 279In-Reply-To: <0>
 280References: <0>
 281---
 282Message-Id: <2>
 283In-Reply-To: <0>
 284References: <0>
 285EOF
 286
 287test_expect_success 'thread' '
 288        check_threading expect.thread --thread master
 289'
 290
 291cat > expect.in-reply-to <<EOF
 292---
 293Message-Id: <0>
 294In-Reply-To: <1>
 295References: <1>
 296---
 297Message-Id: <2>
 298In-Reply-To: <1>
 299References: <1>
 300---
 301Message-Id: <3>
 302In-Reply-To: <1>
 303References: <1>
 304EOF
 305
 306test_expect_success 'thread in-reply-to' '
 307        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 308                --thread master
 309'
 310
 311cat > expect.cover-letter <<EOF
 312---
 313Message-Id: <0>
 314---
 315Message-Id: <1>
 316In-Reply-To: <0>
 317References: <0>
 318---
 319Message-Id: <2>
 320In-Reply-To: <0>
 321References: <0>
 322---
 323Message-Id: <3>
 324In-Reply-To: <0>
 325References: <0>
 326EOF
 327
 328test_expect_success 'thread cover-letter' '
 329        check_threading expect.cover-letter --cover-letter --thread master
 330'
 331
 332cat > expect.cl-irt <<EOF
 333---
 334Message-Id: <0>
 335In-Reply-To: <1>
 336References: <1>
 337---
 338Message-Id: <2>
 339In-Reply-To: <0>
 340References: <1>
 341        <0>
 342---
 343Message-Id: <3>
 344In-Reply-To: <0>
 345References: <1>
 346        <0>
 347---
 348Message-Id: <4>
 349In-Reply-To: <0>
 350References: <1>
 351        <0>
 352EOF
 353
 354test_expect_success 'thread cover-letter in-reply-to' '
 355        check_threading expect.cl-irt --cover-letter \
 356                --in-reply-to="<test.message>" --thread master
 357'
 358
 359test_expect_success 'thread explicit shallow' '
 360        check_threading expect.cl-irt --cover-letter \
 361                --in-reply-to="<test.message>" --thread=shallow master
 362'
 363
 364cat > expect.deep <<EOF
 365---
 366Message-Id: <0>
 367---
 368Message-Id: <1>
 369In-Reply-To: <0>
 370References: <0>
 371---
 372Message-Id: <2>
 373In-Reply-To: <1>
 374References: <0>
 375        <1>
 376EOF
 377
 378test_expect_success 'thread deep' '
 379        check_threading expect.deep --thread=deep master
 380'
 381
 382cat > expect.deep-irt <<EOF
 383---
 384Message-Id: <0>
 385In-Reply-To: <1>
 386References: <1>
 387---
 388Message-Id: <2>
 389In-Reply-To: <0>
 390References: <1>
 391        <0>
 392---
 393Message-Id: <3>
 394In-Reply-To: <2>
 395References: <1>
 396        <0>
 397        <2>
 398EOF
 399
 400test_expect_success 'thread deep in-reply-to' '
 401        check_threading expect.deep-irt  --thread=deep \
 402                --in-reply-to="<test.message>" master
 403'
 404
 405cat > expect.deep-cl <<EOF
 406---
 407Message-Id: <0>
 408---
 409Message-Id: <1>
 410In-Reply-To: <0>
 411References: <0>
 412---
 413Message-Id: <2>
 414In-Reply-To: <1>
 415References: <0>
 416        <1>
 417---
 418Message-Id: <3>
 419In-Reply-To: <2>
 420References: <0>
 421        <1>
 422        <2>
 423EOF
 424
 425test_expect_success 'thread deep cover-letter' '
 426        check_threading expect.deep-cl --cover-letter --thread=deep master
 427'
 428
 429cat > expect.deep-cl-irt <<EOF
 430---
 431Message-Id: <0>
 432In-Reply-To: <1>
 433References: <1>
 434---
 435Message-Id: <2>
 436In-Reply-To: <0>
 437References: <1>
 438        <0>
 439---
 440Message-Id: <3>
 441In-Reply-To: <2>
 442References: <1>
 443        <0>
 444        <2>
 445---
 446Message-Id: <4>
 447In-Reply-To: <3>
 448References: <1>
 449        <0>
 450        <2>
 451        <3>
 452EOF
 453
 454test_expect_success 'thread deep cover-letter in-reply-to' '
 455        check_threading expect.deep-cl-irt --cover-letter \
 456                --in-reply-to="<test.message>" --thread=deep master
 457'
 458
 459test_expect_success 'thread via config' '
 460        test_config format.thread true &&
 461        check_threading expect.thread master
 462'
 463
 464test_expect_success 'thread deep via config' '
 465        test_config format.thread deep &&
 466        check_threading expect.deep master
 467'
 468
 469test_expect_success 'thread config + override' '
 470        test_config format.thread deep &&
 471        check_threading expect.thread --thread master
 472'
 473
 474test_expect_success 'thread config + --no-thread' '
 475        test_config format.thread deep &&
 476        check_threading expect.no-threading --no-thread master
 477'
 478
 479test_expect_success 'excessive subject' '
 480
 481        rm -rf patches/ &&
 482        git checkout side &&
 483        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 484        git update-index file &&
 485        git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
 486        git format-patch -o patches/ master..side &&
 487        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 488'
 489
 490test_expect_success 'cover-letter inherits diff options' '
 491
 492        git mv file foo &&
 493        git commit -m foo &&
 494        git format-patch --cover-letter -1 &&
 495        check_patch 0000-cover-letter.patch &&
 496        ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
 497        git format-patch --cover-letter -1 -M &&
 498        grep "file => foo .* 0 *\$" 0000-cover-letter.patch
 499
 500'
 501
 502cat > expect << EOF
 503  This is an excessively long subject line for a message due to the
 504    habit some projects have of not having a short, one-line subject at
 505    the start of the commit message, but rather sticking a whole
 506    paragraph right at the start as the only thing in the commit
 507    message. It had better not become the filename for the patch.
 508  foo
 509
 510EOF
 511
 512test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 513
 514        git format-patch --cover-letter -2 &&
 515        sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
 516        test_cmp expect output
 517
 518'
 519
 520cat > expect << EOF
 521index 40f36c6..2dc5c23 100644
 522--- a/file
 523+++ b/file
 524@@ -13,4 +13,20 @@ C
 525 10
 526 D
 527 E
 528 F
 529+5
 530EOF
 531
 532test_expect_success 'format-patch respects -U' '
 533
 534        git format-patch -U4 -2 &&
 535        sed -e "1,/^diff/d" -e "/^+5/q" \
 536                <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
 537                >output &&
 538        test_cmp expect output
 539
 540'
 541
 542cat > expect << EOF
 543
 544diff --git a/file b/file
 545index 40f36c6..2dc5c23 100644
 546--- a/file
 547+++ b/file
 548@@ -14,3 +14,19 @@ C
 549 D
 550 E
 551 F
 552+5
 553EOF
 554
 555test_expect_success 'format-patch -p suppresses stat' '
 556
 557        git format-patch -p -2 &&
 558        sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 559        test_cmp expect output
 560
 561'
 562
 563test_expect_success 'format-patch from a subdirectory (1)' '
 564        filename=$(
 565                rm -rf sub &&
 566                mkdir -p sub/dir &&
 567                cd sub/dir &&
 568                git format-patch -1
 569        ) &&
 570        case "$filename" in
 571        0*)
 572                ;; # ok
 573        *)
 574                echo "Oops? $filename"
 575                false
 576                ;;
 577        esac &&
 578        test -f "$filename"
 579'
 580
 581test_expect_success 'format-patch from a subdirectory (2)' '
 582        filename=$(
 583                rm -rf sub &&
 584                mkdir -p sub/dir &&
 585                cd sub/dir &&
 586                git format-patch -1 -o ..
 587        ) &&
 588        case "$filename" in
 589        ../0*)
 590                ;; # ok
 591        *)
 592                echo "Oops? $filename"
 593                false
 594                ;;
 595        esac &&
 596        basename=$(expr "$filename" : ".*/\(.*\)") &&
 597        test -f "sub/$basename"
 598'
 599
 600test_expect_success 'format-patch from a subdirectory (3)' '
 601        rm -f 0* &&
 602        filename=$(
 603                rm -rf sub &&
 604                mkdir -p sub/dir &&
 605                cd sub/dir &&
 606                git format-patch -1 -o "$TRASH_DIRECTORY"
 607        ) &&
 608        basename=$(expr "$filename" : ".*/\(.*\)") &&
 609        test -f "$basename"
 610'
 611
 612test_expect_success 'format-patch --in-reply-to' '
 613        git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
 614        grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
 615        grep "^References: <baz@foo.bar>" patch8
 616'
 617
 618test_expect_success 'format-patch --signoff' '
 619        git format-patch -1 --signoff --stdout >out &&
 620        grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
 621'
 622
 623test_expect_success 'format-patch --notes --signoff' '
 624        git notes --ref test add -m "test message" HEAD &&
 625        git format-patch -1 --signoff --stdout --notes=test >out &&
 626        # Three dashes must come after S-o-b
 627        ! sed "/^Signed-off-by: /q" out | grep "test message" &&
 628        sed "1,/^Signed-off-by: /d" out | grep "test message" &&
 629        # Notes message must come after three dashes
 630        ! sed "/^---$/q" out | grep "test message" &&
 631        sed "1,/^---$/d" out | grep "test message"
 632'
 633
 634echo "fatal: --name-only does not make sense" > expect.name-only
 635echo "fatal: --name-status does not make sense" > expect.name-status
 636echo "fatal: --check does not make sense" > expect.check
 637
 638test_expect_success 'options no longer allowed for format-patch' '
 639        test_must_fail git format-patch --name-only 2> output &&
 640        test_i18ncmp expect.name-only output &&
 641        test_must_fail git format-patch --name-status 2> output &&
 642        test_i18ncmp expect.name-status output &&
 643        test_must_fail git format-patch --check 2> output &&
 644        test_i18ncmp expect.check output'
 645
 646test_expect_success 'format-patch --numstat should produce a patch' '
 647        git format-patch --numstat --stdout master..side > output &&
 648        test 6 = $(grep "^diff --git a/" output | wc -l)'
 649
 650test_expect_success 'format-patch -- <path>' '
 651        git format-patch master..side -- file 2>error &&
 652        ! grep "Use .--" error
 653'
 654
 655test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
 656        git format-patch --ignore-if-in-upstream HEAD
 657'
 658
 659test_expect_success 'format-patch --signature' '
 660        git format-patch --stdout --signature="my sig" -1 >output &&
 661        grep "my sig" output
 662'
 663
 664test_expect_success 'format-patch with format.signature config' '
 665        git config format.signature "config sig" &&
 666        git format-patch --stdout -1 >output &&
 667        grep "config sig" output
 668'
 669
 670test_expect_success 'format-patch --signature overrides format.signature' '
 671        git config format.signature "config sig" &&
 672        git format-patch --stdout --signature="overrides" -1 >output &&
 673        ! grep "config sig" output &&
 674        grep "overrides" output
 675'
 676
 677test_expect_success 'format-patch --no-signature ignores format.signature' '
 678        git config format.signature "config sig" &&
 679        git format-patch --stdout --signature="my sig" --no-signature \
 680                -1 >output &&
 681        check_patch output &&
 682        ! grep "config sig" output &&
 683        ! grep "my sig" output &&
 684        ! grep "^-- \$" output
 685'
 686
 687test_expect_success 'format-patch --signature --cover-letter' '
 688        git config --unset-all format.signature &&
 689        git format-patch --stdout --signature="my sig" --cover-letter \
 690                -1 >output &&
 691        grep "my sig" output &&
 692        test 2 = $(grep "my sig" output | wc -l)
 693'
 694
 695test_expect_success 'format.signature="" supresses signatures' '
 696        git config format.signature "" &&
 697        git format-patch --stdout -1 >output &&
 698        check_patch output &&
 699        ! grep "^-- \$" output
 700'
 701
 702test_expect_success 'format-patch --no-signature supresses signatures' '
 703        git config --unset-all format.signature &&
 704        git format-patch --stdout --no-signature -1 >output &&
 705        check_patch output &&
 706        ! grep "^-- \$" output
 707'
 708
 709test_expect_success 'format-patch --signature="" supresses signatures' '
 710        git format-patch --stdout --signature="" -1 >output &&
 711        check_patch output &&
 712        ! grep "^-- \$" output
 713'
 714
 715test_expect_success TTY 'format-patch --stdout paginates' '
 716        rm -f pager_used &&
 717        (
 718                GIT_PAGER="wc >pager_used" &&
 719                export GIT_PAGER &&
 720                test_terminal git format-patch --stdout --all
 721        ) &&
 722        test_path_is_file pager_used
 723'
 724
 725 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
 726        rm -f pager_used &&
 727        (
 728                GIT_PAGER="wc >pager_used" &&
 729                export GIT_PAGER &&
 730                test_terminal git --no-pager format-patch --stdout --all &&
 731                test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
 732        ) &&
 733        test_path_is_missing pager_used &&
 734        test_path_is_missing .git/pager_used
 735'
 736
 737test_expect_success 'format-patch handles multi-line subjects' '
 738        rm -rf patches/ &&
 739        echo content >>file &&
 740        for i in one two three; do echo $i; done >msg &&
 741        git add file &&
 742        git commit -F msg &&
 743        git format-patch -o patches -1 &&
 744        grep ^Subject: patches/0001-one.patch >actual &&
 745        echo "Subject: [PATCH] one two three" >expect &&
 746        test_cmp expect actual
 747'
 748
 749test_expect_success 'format-patch handles multi-line encoded subjects' '
 750        rm -rf patches/ &&
 751        echo content >>file &&
 752        for i in en två tre; do echo $i; done >msg &&
 753        git add file &&
 754        git commit -F msg &&
 755        git format-patch -o patches -1 &&
 756        grep ^Subject: patches/0001-en.patch >actual &&
 757        echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
 758        test_cmp expect actual
 759'
 760
 761M8="foo bar "
 762M64=$M8$M8$M8$M8$M8$M8$M8$M8
 763M512=$M64$M64$M64$M64$M64$M64$M64$M64
 764cat >expect <<'EOF'
 765Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 766 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 767 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 768 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 769 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 770 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 771 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 772 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 773 foo bar foo bar foo bar foo bar
 774EOF
 775test_expect_success 'format-patch wraps extremely long headers (ascii)' '
 776        echo content >>file &&
 777        git add file &&
 778        git commit -m "$M512" &&
 779        git format-patch --stdout -1 >patch &&
 780        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 781        test_cmp expect subject
 782'
 783
 784M8="föö bar "
 785M64=$M8$M8$M8$M8$M8$M8$M8$M8
 786M512=$M64$M64$M64$M64$M64$M64$M64$M64
 787cat >expect <<'EOF'
 788Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 789 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 790 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 791 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 792 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 793 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 794 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 795 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 796 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 797 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 798 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 799 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 800 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 801 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 802 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 803 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 804 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 805 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 806 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 807 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 808 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 809 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 810EOF
 811test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
 812        rm -rf patches/ &&
 813        echo content >>file &&
 814        git add file &&
 815        git commit -m "$M512" &&
 816        git format-patch --stdout -1 >patch &&
 817        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 818        test_cmp expect subject
 819'
 820
 821M8="foo_bar_"
 822M64=$M8$M8$M8$M8$M8$M8$M8$M8
 823cat >expect <<EOF
 824From: $M64
 825 <foobar@foo.bar>
 826EOF
 827test_expect_success 'format-patch wraps non-quotable headers' '
 828        rm -rf patches/ &&
 829        echo content >>file &&
 830        git add file &&
 831        git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
 832        git format-patch --stdout -1 >patch &&
 833        sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
 834        test_cmp expect from
 835'
 836
 837check_author() {
 838        echo content >>file &&
 839        git add file &&
 840        GIT_AUTHOR_NAME=$1 git commit -m author-check &&
 841        git format-patch --stdout -1 >patch &&
 842        grep ^From: patch >actual &&
 843        test_cmp expect actual
 844}
 845
 846cat >expect <<'EOF'
 847From: "Foo B. Bar" <author@example.com>
 848EOF
 849test_expect_success 'format-patch quotes dot in headers' '
 850        check_author "Foo B. Bar"
 851'
 852
 853cat >expect <<'EOF'
 854From: "Foo \"The Baz\" Bar" <author@example.com>
 855EOF
 856test_expect_success 'format-patch quotes double-quote in headers' '
 857        check_author "Foo \"The Baz\" Bar"
 858'
 859
 860cat >expect <<'EOF'
 861From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
 862EOF
 863test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
 864        check_author "Föo B. Bar"
 865'
 866
 867cat >expect <<'EOF'
 868Subject: header with . in it
 869EOF
 870test_expect_success 'subject lines do not have 822 atom-quoting' '
 871        echo content >>file &&
 872        git add file &&
 873        git commit -m "header with . in it" &&
 874        git format-patch -k -1 --stdout >patch &&
 875        grep ^Subject: patch >actual &&
 876        test_cmp expect actual
 877'
 878
 879cat >expect <<'EOF'
 880Subject: [PREFIX 1/1] header with . in it
 881EOF
 882test_expect_success 'subject prefixes have space prepended' '
 883        git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
 884        grep ^Subject: patch >actual &&
 885        test_cmp expect actual
 886'
 887
 888cat >expect <<'EOF'
 889Subject: [1/1] header with . in it
 890EOF
 891test_expect_success 'empty subject prefix does not have extra space' '
 892        git format-patch -n -1 --stdout --subject-prefix= >patch &&
 893        grep ^Subject: patch >actual &&
 894        test_cmp expect actual
 895'
 896
 897test_expect_success 'format patch ignores color.ui' '
 898        test_unconfig color.ui &&
 899        git format-patch --stdout -1 >expect &&
 900        test_config color.ui always &&
 901        git format-patch --stdout -1 >actual &&
 902        test_cmp expect actual
 903'
 904
 905test_done