t / t4014-format-patch.shon commit format-patch: give --reroll-count a short synonym -v (7952ea6)
   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
 240test_expect_success 'reroll count' '
 241        rm -fr patches &&
 242        git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
 243        ! grep -v "^patches/v4-000[0-3]-" list &&
 244        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 245        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 246'
 247
 248test_expect_success 'reroll count (-v)' '
 249        rm -fr patches &&
 250        git format-patch -o patches --cover-letter -v4 master..side >list &&
 251        ! grep -v "^patches/v4-000[0-3]-" list &&
 252        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 253        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 254'
 255
 256check_threading () {
 257        expect="$1" &&
 258        shift &&
 259        (git format-patch --stdout "$@"; echo $? > status.out) |
 260        # Prints everything between the Message-ID and In-Reply-To,
 261        # and replaces all Message-ID-lookalikes by a sequence number
 262        "$PERL_PATH" -ne '
 263                if (/^(message-id|references|in-reply-to)/i) {
 264                        $printing = 1;
 265                } elsif (/^\S/) {
 266                        $printing = 0;
 267                }
 268                if ($printing) {
 269                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 270                        for $k (keys %h) {s/$k/$h{$k}/};
 271                        print;
 272                }
 273                print "---\n" if /^From /i;
 274        ' > actual &&
 275        test 0 = "$(cat status.out)" &&
 276        test_cmp "$expect" actual
 277}
 278
 279cat >> expect.no-threading <<EOF
 280---
 281---
 282---
 283EOF
 284
 285test_expect_success 'no threading' '
 286        git checkout side &&
 287        check_threading expect.no-threading master
 288'
 289
 290cat > expect.thread <<EOF
 291---
 292Message-Id: <0>
 293---
 294Message-Id: <1>
 295In-Reply-To: <0>
 296References: <0>
 297---
 298Message-Id: <2>
 299In-Reply-To: <0>
 300References: <0>
 301EOF
 302
 303test_expect_success 'thread' '
 304        check_threading expect.thread --thread master
 305'
 306
 307cat > expect.in-reply-to <<EOF
 308---
 309Message-Id: <0>
 310In-Reply-To: <1>
 311References: <1>
 312---
 313Message-Id: <2>
 314In-Reply-To: <1>
 315References: <1>
 316---
 317Message-Id: <3>
 318In-Reply-To: <1>
 319References: <1>
 320EOF
 321
 322test_expect_success 'thread in-reply-to' '
 323        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 324                --thread master
 325'
 326
 327cat > expect.cover-letter <<EOF
 328---
 329Message-Id: <0>
 330---
 331Message-Id: <1>
 332In-Reply-To: <0>
 333References: <0>
 334---
 335Message-Id: <2>
 336In-Reply-To: <0>
 337References: <0>
 338---
 339Message-Id: <3>
 340In-Reply-To: <0>
 341References: <0>
 342EOF
 343
 344test_expect_success 'thread cover-letter' '
 345        check_threading expect.cover-letter --cover-letter --thread master
 346'
 347
 348cat > expect.cl-irt <<EOF
 349---
 350Message-Id: <0>
 351In-Reply-To: <1>
 352References: <1>
 353---
 354Message-Id: <2>
 355In-Reply-To: <0>
 356References: <1>
 357        <0>
 358---
 359Message-Id: <3>
 360In-Reply-To: <0>
 361References: <1>
 362        <0>
 363---
 364Message-Id: <4>
 365In-Reply-To: <0>
 366References: <1>
 367        <0>
 368EOF
 369
 370test_expect_success 'thread cover-letter in-reply-to' '
 371        check_threading expect.cl-irt --cover-letter \
 372                --in-reply-to="<test.message>" --thread master
 373'
 374
 375test_expect_success 'thread explicit shallow' '
 376        check_threading expect.cl-irt --cover-letter \
 377                --in-reply-to="<test.message>" --thread=shallow master
 378'
 379
 380cat > expect.deep <<EOF
 381---
 382Message-Id: <0>
 383---
 384Message-Id: <1>
 385In-Reply-To: <0>
 386References: <0>
 387---
 388Message-Id: <2>
 389In-Reply-To: <1>
 390References: <0>
 391        <1>
 392EOF
 393
 394test_expect_success 'thread deep' '
 395        check_threading expect.deep --thread=deep master
 396'
 397
 398cat > expect.deep-irt <<EOF
 399---
 400Message-Id: <0>
 401In-Reply-To: <1>
 402References: <1>
 403---
 404Message-Id: <2>
 405In-Reply-To: <0>
 406References: <1>
 407        <0>
 408---
 409Message-Id: <3>
 410In-Reply-To: <2>
 411References: <1>
 412        <0>
 413        <2>
 414EOF
 415
 416test_expect_success 'thread deep in-reply-to' '
 417        check_threading expect.deep-irt  --thread=deep \
 418                --in-reply-to="<test.message>" master
 419'
 420
 421cat > expect.deep-cl <<EOF
 422---
 423Message-Id: <0>
 424---
 425Message-Id: <1>
 426In-Reply-To: <0>
 427References: <0>
 428---
 429Message-Id: <2>
 430In-Reply-To: <1>
 431References: <0>
 432        <1>
 433---
 434Message-Id: <3>
 435In-Reply-To: <2>
 436References: <0>
 437        <1>
 438        <2>
 439EOF
 440
 441test_expect_success 'thread deep cover-letter' '
 442        check_threading expect.deep-cl --cover-letter --thread=deep master
 443'
 444
 445cat > expect.deep-cl-irt <<EOF
 446---
 447Message-Id: <0>
 448In-Reply-To: <1>
 449References: <1>
 450---
 451Message-Id: <2>
 452In-Reply-To: <0>
 453References: <1>
 454        <0>
 455---
 456Message-Id: <3>
 457In-Reply-To: <2>
 458References: <1>
 459        <0>
 460        <2>
 461---
 462Message-Id: <4>
 463In-Reply-To: <3>
 464References: <1>
 465        <0>
 466        <2>
 467        <3>
 468EOF
 469
 470test_expect_success 'thread deep cover-letter in-reply-to' '
 471        check_threading expect.deep-cl-irt --cover-letter \
 472                --in-reply-to="<test.message>" --thread=deep master
 473'
 474
 475test_expect_success 'thread via config' '
 476        test_config format.thread true &&
 477        check_threading expect.thread master
 478'
 479
 480test_expect_success 'thread deep via config' '
 481        test_config format.thread deep &&
 482        check_threading expect.deep master
 483'
 484
 485test_expect_success 'thread config + override' '
 486        test_config format.thread deep &&
 487        check_threading expect.thread --thread master
 488'
 489
 490test_expect_success 'thread config + --no-thread' '
 491        test_config format.thread deep &&
 492        check_threading expect.no-threading --no-thread master
 493'
 494
 495test_expect_success 'excessive subject' '
 496
 497        rm -rf patches/ &&
 498        git checkout side &&
 499        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 500        git update-index file &&
 501        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." &&
 502        git format-patch -o patches/ master..side &&
 503        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 504'
 505
 506test_expect_success 'cover-letter inherits diff options' '
 507
 508        git mv file foo &&
 509        git commit -m foo &&
 510        git format-patch --cover-letter -1 &&
 511        check_patch 0000-cover-letter.patch &&
 512        ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
 513        git format-patch --cover-letter -1 -M &&
 514        grep "file => foo .* 0 *\$" 0000-cover-letter.patch
 515
 516'
 517
 518cat > expect << EOF
 519  This is an excessively long subject line for a message due to the
 520    habit some projects have of not having a short, one-line subject at
 521    the start of the commit message, but rather sticking a whole
 522    paragraph right at the start as the only thing in the commit
 523    message. It had better not become the filename for the patch.
 524  foo
 525
 526EOF
 527
 528test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 529
 530        git format-patch --cover-letter -2 &&
 531        sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
 532        test_cmp expect output
 533
 534'
 535
 536cat > expect << EOF
 537index 40f36c6..2dc5c23 100644
 538--- a/file
 539+++ b/file
 540@@ -13,4 +13,20 @@ C
 541 10
 542 D
 543 E
 544 F
 545+5
 546EOF
 547
 548test_expect_success 'format-patch respects -U' '
 549
 550        git format-patch -U4 -2 &&
 551        sed -e "1,/^diff/d" -e "/^+5/q" \
 552                <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
 553                >output &&
 554        test_cmp expect output
 555
 556'
 557
 558cat > expect << EOF
 559
 560diff --git a/file b/file
 561index 40f36c6..2dc5c23 100644
 562--- a/file
 563+++ b/file
 564@@ -14,3 +14,19 @@ C
 565 D
 566 E
 567 F
 568+5
 569EOF
 570
 571test_expect_success 'format-patch -p suppresses stat' '
 572
 573        git format-patch -p -2 &&
 574        sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 575        test_cmp expect output
 576
 577'
 578
 579test_expect_success 'format-patch from a subdirectory (1)' '
 580        filename=$(
 581                rm -rf sub &&
 582                mkdir -p sub/dir &&
 583                cd sub/dir &&
 584                git format-patch -1
 585        ) &&
 586        case "$filename" in
 587        0*)
 588                ;; # ok
 589        *)
 590                echo "Oops? $filename"
 591                false
 592                ;;
 593        esac &&
 594        test -f "$filename"
 595'
 596
 597test_expect_success 'format-patch from a subdirectory (2)' '
 598        filename=$(
 599                rm -rf sub &&
 600                mkdir -p sub/dir &&
 601                cd sub/dir &&
 602                git format-patch -1 -o ..
 603        ) &&
 604        case "$filename" in
 605        ../0*)
 606                ;; # ok
 607        *)
 608                echo "Oops? $filename"
 609                false
 610                ;;
 611        esac &&
 612        basename=$(expr "$filename" : ".*/\(.*\)") &&
 613        test -f "sub/$basename"
 614'
 615
 616test_expect_success 'format-patch from a subdirectory (3)' '
 617        rm -f 0* &&
 618        filename=$(
 619                rm -rf sub &&
 620                mkdir -p sub/dir &&
 621                cd sub/dir &&
 622                git format-patch -1 -o "$TRASH_DIRECTORY"
 623        ) &&
 624        basename=$(expr "$filename" : ".*/\(.*\)") &&
 625        test -f "$basename"
 626'
 627
 628test_expect_success 'format-patch --in-reply-to' '
 629        git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
 630        grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
 631        grep "^References: <baz@foo.bar>" patch8
 632'
 633
 634test_expect_success 'format-patch --signoff' '
 635        git format-patch -1 --signoff --stdout |
 636        grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
 637'
 638
 639echo "fatal: --name-only does not make sense" > expect.name-only
 640echo "fatal: --name-status does not make sense" > expect.name-status
 641echo "fatal: --check does not make sense" > expect.check
 642
 643test_expect_success 'options no longer allowed for format-patch' '
 644        test_must_fail git format-patch --name-only 2> output &&
 645        test_i18ncmp expect.name-only output &&
 646        test_must_fail git format-patch --name-status 2> output &&
 647        test_i18ncmp expect.name-status output &&
 648        test_must_fail git format-patch --check 2> output &&
 649        test_i18ncmp expect.check output'
 650
 651test_expect_success 'format-patch --numstat should produce a patch' '
 652        git format-patch --numstat --stdout master..side > output &&
 653        test 6 = $(grep "^diff --git a/" output | wc -l)'
 654
 655test_expect_success 'format-patch -- <path>' '
 656        git format-patch master..side -- file 2>error &&
 657        ! grep "Use .--" error
 658'
 659
 660test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
 661        git format-patch --ignore-if-in-upstream HEAD
 662'
 663
 664test_expect_success 'format-patch --signature' '
 665        git format-patch --stdout --signature="my sig" -1 >output &&
 666        grep "my sig" output
 667'
 668
 669test_expect_success 'format-patch with format.signature config' '
 670        git config format.signature "config sig" &&
 671        git format-patch --stdout -1 >output &&
 672        grep "config sig" output
 673'
 674
 675test_expect_success 'format-patch --signature overrides format.signature' '
 676        git config format.signature "config sig" &&
 677        git format-patch --stdout --signature="overrides" -1 >output &&
 678        ! grep "config sig" output &&
 679        grep "overrides" output
 680'
 681
 682test_expect_success 'format-patch --no-signature ignores format.signature' '
 683        git config format.signature "config sig" &&
 684        git format-patch --stdout --signature="my sig" --no-signature \
 685                -1 >output &&
 686        check_patch output &&
 687        ! grep "config sig" output &&
 688        ! grep "my sig" output &&
 689        ! grep "^-- \$" output
 690'
 691
 692test_expect_success 'format-patch --signature --cover-letter' '
 693        git config --unset-all format.signature &&
 694        git format-patch --stdout --signature="my sig" --cover-letter \
 695                -1 >output &&
 696        grep "my sig" output &&
 697        test 2 = $(grep "my sig" output | wc -l)
 698'
 699
 700test_expect_success 'format.signature="" supresses signatures' '
 701        git config format.signature "" &&
 702        git format-patch --stdout -1 >output &&
 703        check_patch output &&
 704        ! grep "^-- \$" output
 705'
 706
 707test_expect_success 'format-patch --no-signature supresses signatures' '
 708        git config --unset-all format.signature &&
 709        git format-patch --stdout --no-signature -1 >output &&
 710        check_patch output &&
 711        ! grep "^-- \$" output
 712'
 713
 714test_expect_success 'format-patch --signature="" supresses signatures' '
 715        git format-patch --stdout --signature="" -1 >output &&
 716        check_patch output &&
 717        ! grep "^-- \$" output
 718'
 719
 720test_expect_success TTY 'format-patch --stdout paginates' '
 721        rm -f pager_used &&
 722        (
 723                GIT_PAGER="wc >pager_used" &&
 724                export GIT_PAGER &&
 725                test_terminal git format-patch --stdout --all
 726        ) &&
 727        test_path_is_file pager_used
 728'
 729
 730 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
 731        rm -f pager_used &&
 732        (
 733                GIT_PAGER="wc >pager_used" &&
 734                export GIT_PAGER &&
 735                test_terminal git --no-pager format-patch --stdout --all &&
 736                test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
 737        ) &&
 738        test_path_is_missing pager_used &&
 739        test_path_is_missing .git/pager_used
 740'
 741
 742test_expect_success 'format-patch handles multi-line subjects' '
 743        rm -rf patches/ &&
 744        echo content >>file &&
 745        for i in one two three; do echo $i; done >msg &&
 746        git add file &&
 747        git commit -F msg &&
 748        git format-patch -o patches -1 &&
 749        grep ^Subject: patches/0001-one.patch >actual &&
 750        echo "Subject: [PATCH] one two three" >expect &&
 751        test_cmp expect actual
 752'
 753
 754test_expect_success 'format-patch handles multi-line encoded subjects' '
 755        rm -rf patches/ &&
 756        echo content >>file &&
 757        for i in en två tre; do echo $i; done >msg &&
 758        git add file &&
 759        git commit -F msg &&
 760        git format-patch -o patches -1 &&
 761        grep ^Subject: patches/0001-en.patch >actual &&
 762        echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
 763        test_cmp expect actual
 764'
 765
 766M8="foo bar "
 767M64=$M8$M8$M8$M8$M8$M8$M8$M8
 768M512=$M64$M64$M64$M64$M64$M64$M64$M64
 769cat >expect <<'EOF'
 770Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 771 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 772 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 773 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 774 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 775 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 776 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 777 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 778 foo bar foo bar foo bar foo bar
 779EOF
 780test_expect_success 'format-patch wraps extremely long headers (ascii)' '
 781        echo content >>file &&
 782        git add file &&
 783        git commit -m "$M512" &&
 784        git format-patch --stdout -1 >patch &&
 785        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 786        test_cmp expect subject
 787'
 788
 789M8="föö bar "
 790M64=$M8$M8$M8$M8$M8$M8$M8$M8
 791M512=$M64$M64$M64$M64$M64$M64$M64$M64
 792cat >expect <<'EOF'
 793Subject: [PATCH] =?UTF-8?q?f=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=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 810 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 811 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 812 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 813 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 814 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 815EOF
 816test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
 817        rm -rf patches/ &&
 818        echo content >>file &&
 819        git add file &&
 820        git commit -m "$M512" &&
 821        git format-patch --stdout -1 >patch &&
 822        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 823        test_cmp expect subject
 824'
 825
 826M8="foo_bar_"
 827M64=$M8$M8$M8$M8$M8$M8$M8$M8
 828cat >expect <<EOF
 829From: $M64
 830 <foobar@foo.bar>
 831EOF
 832test_expect_success 'format-patch wraps non-quotable headers' '
 833        rm -rf patches/ &&
 834        echo content >>file &&
 835        git add file &&
 836        git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
 837        git format-patch --stdout -1 >patch &&
 838        sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
 839        test_cmp expect from
 840'
 841
 842check_author() {
 843        echo content >>file &&
 844        git add file &&
 845        GIT_AUTHOR_NAME=$1 git commit -m author-check &&
 846        git format-patch --stdout -1 >patch &&
 847        grep ^From: patch >actual &&
 848        test_cmp expect actual
 849}
 850
 851cat >expect <<'EOF'
 852From: "Foo B. Bar" <author@example.com>
 853EOF
 854test_expect_success 'format-patch quotes dot in headers' '
 855        check_author "Foo B. Bar"
 856'
 857
 858cat >expect <<'EOF'
 859From: "Foo \"The Baz\" Bar" <author@example.com>
 860EOF
 861test_expect_success 'format-patch quotes double-quote in headers' '
 862        check_author "Foo \"The Baz\" Bar"
 863'
 864
 865cat >expect <<'EOF'
 866From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
 867EOF
 868test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
 869        check_author "Föo B. Bar"
 870'
 871
 872cat >expect <<'EOF'
 873Subject: header with . in it
 874EOF
 875test_expect_success 'subject lines do not have 822 atom-quoting' '
 876        echo content >>file &&
 877        git add file &&
 878        git commit -m "header with . in it" &&
 879        git format-patch -k -1 --stdout >patch &&
 880        grep ^Subject: patch >actual &&
 881        test_cmp expect actual
 882'
 883
 884cat >expect <<'EOF'
 885Subject: [PREFIX 1/1] header with . in it
 886EOF
 887test_expect_success 'subject prefixes have space prepended' '
 888        git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
 889        grep ^Subject: patch >actual &&
 890        test_cmp expect actual
 891'
 892
 893cat >expect <<'EOF'
 894Subject: [1/1] header with . in it
 895EOF
 896test_expect_success 'empty subject prefix does not have extra space' '
 897        git format-patch -n -1 --stdout --subject-prefix= >patch &&
 898        grep ^Subject: patch >actual &&
 899        test_cmp expect actual
 900'
 901
 902test_expect_success 'format patch ignores color.ui' '
 903        test_unconfig color.ui &&
 904        git format-patch --stdout -1 >expect &&
 905        test_config color.ui always &&
 906        git format-patch --stdout -1 >actual &&
 907        test_cmp expect actual
 908'
 909
 910test_done