bea63814e6a58e930aa46e6728cc3442fc4ea4f4
   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        # Notes message 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'
 630
 631echo "fatal: --name-only does not make sense" > expect.name-only
 632echo "fatal: --name-status does not make sense" > expect.name-status
 633echo "fatal: --check does not make sense" > expect.check
 634
 635test_expect_success 'options no longer allowed for format-patch' '
 636        test_must_fail git format-patch --name-only 2> output &&
 637        test_i18ncmp expect.name-only output &&
 638        test_must_fail git format-patch --name-status 2> output &&
 639        test_i18ncmp expect.name-status output &&
 640        test_must_fail git format-patch --check 2> output &&
 641        test_i18ncmp expect.check output'
 642
 643test_expect_success 'format-patch --numstat should produce a patch' '
 644        git format-patch --numstat --stdout master..side > output &&
 645        test 6 = $(grep "^diff --git a/" output | wc -l)'
 646
 647test_expect_success 'format-patch -- <path>' '
 648        git format-patch master..side -- file 2>error &&
 649        ! grep "Use .--" error
 650'
 651
 652test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
 653        git format-patch --ignore-if-in-upstream HEAD
 654'
 655
 656test_expect_success 'format-patch --signature' '
 657        git format-patch --stdout --signature="my sig" -1 >output &&
 658        grep "my sig" output
 659'
 660
 661test_expect_success 'format-patch with format.signature config' '
 662        git config format.signature "config sig" &&
 663        git format-patch --stdout -1 >output &&
 664        grep "config sig" output
 665'
 666
 667test_expect_success 'format-patch --signature overrides format.signature' '
 668        git config format.signature "config sig" &&
 669        git format-patch --stdout --signature="overrides" -1 >output &&
 670        ! grep "config sig" output &&
 671        grep "overrides" output
 672'
 673
 674test_expect_success 'format-patch --no-signature ignores format.signature' '
 675        git config format.signature "config sig" &&
 676        git format-patch --stdout --signature="my sig" --no-signature \
 677                -1 >output &&
 678        check_patch output &&
 679        ! grep "config sig" output &&
 680        ! grep "my sig" output &&
 681        ! grep "^-- \$" output
 682'
 683
 684test_expect_success 'format-patch --signature --cover-letter' '
 685        git config --unset-all format.signature &&
 686        git format-patch --stdout --signature="my sig" --cover-letter \
 687                -1 >output &&
 688        grep "my sig" output &&
 689        test 2 = $(grep "my sig" output | wc -l)
 690'
 691
 692test_expect_success 'format.signature="" supresses signatures' '
 693        git config format.signature "" &&
 694        git format-patch --stdout -1 >output &&
 695        check_patch output &&
 696        ! grep "^-- \$" output
 697'
 698
 699test_expect_success 'format-patch --no-signature supresses signatures' '
 700        git config --unset-all format.signature &&
 701        git format-patch --stdout --no-signature -1 >output &&
 702        check_patch output &&
 703        ! grep "^-- \$" output
 704'
 705
 706test_expect_success 'format-patch --signature="" supresses signatures' '
 707        git format-patch --stdout --signature="" -1 >output &&
 708        check_patch output &&
 709        ! grep "^-- \$" output
 710'
 711
 712test_expect_success TTY 'format-patch --stdout paginates' '
 713        rm -f pager_used &&
 714        (
 715                GIT_PAGER="wc >pager_used" &&
 716                export GIT_PAGER &&
 717                test_terminal git format-patch --stdout --all
 718        ) &&
 719        test_path_is_file pager_used
 720'
 721
 722 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
 723        rm -f pager_used &&
 724        (
 725                GIT_PAGER="wc >pager_used" &&
 726                export GIT_PAGER &&
 727                test_terminal git --no-pager format-patch --stdout --all &&
 728                test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
 729        ) &&
 730        test_path_is_missing pager_used &&
 731        test_path_is_missing .git/pager_used
 732'
 733
 734test_expect_success 'format-patch handles multi-line subjects' '
 735        rm -rf patches/ &&
 736        echo content >>file &&
 737        for i in one two three; do echo $i; done >msg &&
 738        git add file &&
 739        git commit -F msg &&
 740        git format-patch -o patches -1 &&
 741        grep ^Subject: patches/0001-one.patch >actual &&
 742        echo "Subject: [PATCH] one two three" >expect &&
 743        test_cmp expect actual
 744'
 745
 746test_expect_success 'format-patch handles multi-line encoded subjects' '
 747        rm -rf patches/ &&
 748        echo content >>file &&
 749        for i in en två tre; do echo $i; done >msg &&
 750        git add file &&
 751        git commit -F msg &&
 752        git format-patch -o patches -1 &&
 753        grep ^Subject: patches/0001-en.patch >actual &&
 754        echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
 755        test_cmp expect actual
 756'
 757
 758M8="foo bar "
 759M64=$M8$M8$M8$M8$M8$M8$M8$M8
 760M512=$M64$M64$M64$M64$M64$M64$M64$M64
 761cat >expect <<'EOF'
 762Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 763 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 764 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 765 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 766 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 767 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 768 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 769 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 770 foo bar foo bar foo bar foo bar
 771EOF
 772test_expect_success 'format-patch wraps extremely long headers (ascii)' '
 773        echo content >>file &&
 774        git add file &&
 775        git commit -m "$M512" &&
 776        git format-patch --stdout -1 >patch &&
 777        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 778        test_cmp expect subject
 779'
 780
 781M8="föö bar "
 782M64=$M8$M8$M8$M8$M8$M8$M8$M8
 783M512=$M64$M64$M64$M64$M64$M64$M64$M64
 784cat >expect <<'EOF'
 785Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 786 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 787 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 788 =?UTF-8?q?=C3=B6=20bar=20f=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?=
 807EOF
 808test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
 809        rm -rf patches/ &&
 810        echo content >>file &&
 811        git add file &&
 812        git commit -m "$M512" &&
 813        git format-patch --stdout -1 >patch &&
 814        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 815        test_cmp expect subject
 816'
 817
 818M8="foo_bar_"
 819M64=$M8$M8$M8$M8$M8$M8$M8$M8
 820cat >expect <<EOF
 821From: $M64
 822 <foobar@foo.bar>
 823EOF
 824test_expect_success 'format-patch wraps non-quotable headers' '
 825        rm -rf patches/ &&
 826        echo content >>file &&
 827        git add file &&
 828        git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
 829        git format-patch --stdout -1 >patch &&
 830        sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
 831        test_cmp expect from
 832'
 833
 834check_author() {
 835        echo content >>file &&
 836        git add file &&
 837        GIT_AUTHOR_NAME=$1 git commit -m author-check &&
 838        git format-patch --stdout -1 >patch &&
 839        grep ^From: patch >actual &&
 840        test_cmp expect actual
 841}
 842
 843cat >expect <<'EOF'
 844From: "Foo B. Bar" <author@example.com>
 845EOF
 846test_expect_success 'format-patch quotes dot in headers' '
 847        check_author "Foo B. Bar"
 848'
 849
 850cat >expect <<'EOF'
 851From: "Foo \"The Baz\" Bar" <author@example.com>
 852EOF
 853test_expect_success 'format-patch quotes double-quote in headers' '
 854        check_author "Foo \"The Baz\" Bar"
 855'
 856
 857cat >expect <<'EOF'
 858From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
 859EOF
 860test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
 861        check_author "Föo B. Bar"
 862'
 863
 864cat >expect <<'EOF'
 865Subject: header with . in it
 866EOF
 867test_expect_success 'subject lines do not have 822 atom-quoting' '
 868        echo content >>file &&
 869        git add file &&
 870        git commit -m "header with . in it" &&
 871        git format-patch -k -1 --stdout >patch &&
 872        grep ^Subject: patch >actual &&
 873        test_cmp expect actual
 874'
 875
 876cat >expect <<'EOF'
 877Subject: [PREFIX 1/1] header with . in it
 878EOF
 879test_expect_success 'subject prefixes have space prepended' '
 880        git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
 881        grep ^Subject: patch >actual &&
 882        test_cmp expect actual
 883'
 884
 885cat >expect <<'EOF'
 886Subject: [1/1] header with . in it
 887EOF
 888test_expect_success 'empty subject prefix does not have extra space' '
 889        git format-patch -n -1 --stdout --subject-prefix= >patch &&
 890        grep ^Subject: patch >actual &&
 891        test_cmp expect actual
 892'
 893
 894test_expect_success 'format patch ignores color.ui' '
 895        test_unconfig color.ui &&
 896        git format-patch --stdout -1 >expect &&
 897        test_config color.ui always &&
 898        git format-patch --stdout -1 >actual &&
 899        test_cmp expect actual
 900'
 901
 902test_done