0ff99582c6e68844d672e3982f49d216d2014587
   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
 248check_threading () {
 249        expect="$1" &&
 250        shift &&
 251        (git format-patch --stdout "$@"; echo $? > status.out) |
 252        # Prints everything between the Message-ID and In-Reply-To,
 253        # and replaces all Message-ID-lookalikes by a sequence number
 254        "$PERL_PATH" -ne '
 255                if (/^(message-id|references|in-reply-to)/i) {
 256                        $printing = 1;
 257                } elsif (/^\S/) {
 258                        $printing = 0;
 259                }
 260                if ($printing) {
 261                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 262                        for $k (keys %h) {s/$k/$h{$k}/};
 263                        print;
 264                }
 265                print "---\n" if /^From /i;
 266        ' > actual &&
 267        test 0 = "$(cat status.out)" &&
 268        test_cmp "$expect" actual
 269}
 270
 271cat >> expect.no-threading <<EOF
 272---
 273---
 274---
 275EOF
 276
 277test_expect_success 'no threading' '
 278        git checkout side &&
 279        check_threading expect.no-threading master
 280'
 281
 282cat > expect.thread <<EOF
 283---
 284Message-Id: <0>
 285---
 286Message-Id: <1>
 287In-Reply-To: <0>
 288References: <0>
 289---
 290Message-Id: <2>
 291In-Reply-To: <0>
 292References: <0>
 293EOF
 294
 295test_expect_success 'thread' '
 296        check_threading expect.thread --thread master
 297'
 298
 299cat > expect.in-reply-to <<EOF
 300---
 301Message-Id: <0>
 302In-Reply-To: <1>
 303References: <1>
 304---
 305Message-Id: <2>
 306In-Reply-To: <1>
 307References: <1>
 308---
 309Message-Id: <3>
 310In-Reply-To: <1>
 311References: <1>
 312EOF
 313
 314test_expect_success 'thread in-reply-to' '
 315        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 316                --thread master
 317'
 318
 319cat > expect.cover-letter <<EOF
 320---
 321Message-Id: <0>
 322---
 323Message-Id: <1>
 324In-Reply-To: <0>
 325References: <0>
 326---
 327Message-Id: <2>
 328In-Reply-To: <0>
 329References: <0>
 330---
 331Message-Id: <3>
 332In-Reply-To: <0>
 333References: <0>
 334EOF
 335
 336test_expect_success 'thread cover-letter' '
 337        check_threading expect.cover-letter --cover-letter --thread master
 338'
 339
 340cat > expect.cl-irt <<EOF
 341---
 342Message-Id: <0>
 343In-Reply-To: <1>
 344References: <1>
 345---
 346Message-Id: <2>
 347In-Reply-To: <0>
 348References: <1>
 349        <0>
 350---
 351Message-Id: <3>
 352In-Reply-To: <0>
 353References: <1>
 354        <0>
 355---
 356Message-Id: <4>
 357In-Reply-To: <0>
 358References: <1>
 359        <0>
 360EOF
 361
 362test_expect_success 'thread cover-letter in-reply-to' '
 363        check_threading expect.cl-irt --cover-letter \
 364                --in-reply-to="<test.message>" --thread master
 365'
 366
 367test_expect_success 'thread explicit shallow' '
 368        check_threading expect.cl-irt --cover-letter \
 369                --in-reply-to="<test.message>" --thread=shallow master
 370'
 371
 372cat > expect.deep <<EOF
 373---
 374Message-Id: <0>
 375---
 376Message-Id: <1>
 377In-Reply-To: <0>
 378References: <0>
 379---
 380Message-Id: <2>
 381In-Reply-To: <1>
 382References: <0>
 383        <1>
 384EOF
 385
 386test_expect_success 'thread deep' '
 387        check_threading expect.deep --thread=deep master
 388'
 389
 390cat > expect.deep-irt <<EOF
 391---
 392Message-Id: <0>
 393In-Reply-To: <1>
 394References: <1>
 395---
 396Message-Id: <2>
 397In-Reply-To: <0>
 398References: <1>
 399        <0>
 400---
 401Message-Id: <3>
 402In-Reply-To: <2>
 403References: <1>
 404        <0>
 405        <2>
 406EOF
 407
 408test_expect_success 'thread deep in-reply-to' '
 409        check_threading expect.deep-irt  --thread=deep \
 410                --in-reply-to="<test.message>" master
 411'
 412
 413cat > expect.deep-cl <<EOF
 414---
 415Message-Id: <0>
 416---
 417Message-Id: <1>
 418In-Reply-To: <0>
 419References: <0>
 420---
 421Message-Id: <2>
 422In-Reply-To: <1>
 423References: <0>
 424        <1>
 425---
 426Message-Id: <3>
 427In-Reply-To: <2>
 428References: <0>
 429        <1>
 430        <2>
 431EOF
 432
 433test_expect_success 'thread deep cover-letter' '
 434        check_threading expect.deep-cl --cover-letter --thread=deep master
 435'
 436
 437cat > expect.deep-cl-irt <<EOF
 438---
 439Message-Id: <0>
 440In-Reply-To: <1>
 441References: <1>
 442---
 443Message-Id: <2>
 444In-Reply-To: <0>
 445References: <1>
 446        <0>
 447---
 448Message-Id: <3>
 449In-Reply-To: <2>
 450References: <1>
 451        <0>
 452        <2>
 453---
 454Message-Id: <4>
 455In-Reply-To: <3>
 456References: <1>
 457        <0>
 458        <2>
 459        <3>
 460EOF
 461
 462test_expect_success 'thread deep cover-letter in-reply-to' '
 463        check_threading expect.deep-cl-irt --cover-letter \
 464                --in-reply-to="<test.message>" --thread=deep master
 465'
 466
 467test_expect_success 'thread via config' '
 468        test_config format.thread true &&
 469        check_threading expect.thread master
 470'
 471
 472test_expect_success 'thread deep via config' '
 473        test_config format.thread deep &&
 474        check_threading expect.deep master
 475'
 476
 477test_expect_success 'thread config + override' '
 478        test_config format.thread deep &&
 479        check_threading expect.thread --thread master
 480'
 481
 482test_expect_success 'thread config + --no-thread' '
 483        test_config format.thread deep &&
 484        check_threading expect.no-threading --no-thread master
 485'
 486
 487test_expect_success 'excessive subject' '
 488
 489        rm -rf patches/ &&
 490        git checkout side &&
 491        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 492        git update-index file &&
 493        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." &&
 494        git format-patch -o patches/ master..side &&
 495        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 496'
 497
 498test_expect_success 'cover-letter inherits diff options' '
 499
 500        git mv file foo &&
 501        git commit -m foo &&
 502        git format-patch --cover-letter -1 &&
 503        check_patch 0000-cover-letter.patch &&
 504        ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
 505        git format-patch --cover-letter -1 -M &&
 506        grep "file => foo .* 0 *\$" 0000-cover-letter.patch
 507
 508'
 509
 510cat > expect << EOF
 511  This is an excessively long subject line for a message due to the
 512    habit some projects have of not having a short, one-line subject at
 513    the start of the commit message, but rather sticking a whole
 514    paragraph right at the start as the only thing in the commit
 515    message. It had better not become the filename for the patch.
 516  foo
 517
 518EOF
 519
 520test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 521
 522        git format-patch --cover-letter -2 &&
 523        sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
 524        test_cmp expect output
 525
 526'
 527
 528cat > expect << EOF
 529index 40f36c6..2dc5c23 100644
 530--- a/file
 531+++ b/file
 532@@ -13,4 +13,20 @@ C
 533 10
 534 D
 535 E
 536 F
 537+5
 538EOF
 539
 540test_expect_success 'format-patch respects -U' '
 541
 542        git format-patch -U4 -2 &&
 543        sed -e "1,/^diff/d" -e "/^+5/q" \
 544                <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
 545                >output &&
 546        test_cmp expect output
 547
 548'
 549
 550cat > expect << EOF
 551
 552diff --git a/file b/file
 553index 40f36c6..2dc5c23 100644
 554--- a/file
 555+++ b/file
 556@@ -14,3 +14,19 @@ C
 557 D
 558 E
 559 F
 560+5
 561EOF
 562
 563test_expect_success 'format-patch -p suppresses stat' '
 564
 565        git format-patch -p -2 &&
 566        sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 567        test_cmp expect output
 568
 569'
 570
 571test_expect_success 'format-patch from a subdirectory (1)' '
 572        filename=$(
 573                rm -rf sub &&
 574                mkdir -p sub/dir &&
 575                cd sub/dir &&
 576                git format-patch -1
 577        ) &&
 578        case "$filename" in
 579        0*)
 580                ;; # ok
 581        *)
 582                echo "Oops? $filename"
 583                false
 584                ;;
 585        esac &&
 586        test -f "$filename"
 587'
 588
 589test_expect_success 'format-patch from a subdirectory (2)' '
 590        filename=$(
 591                rm -rf sub &&
 592                mkdir -p sub/dir &&
 593                cd sub/dir &&
 594                git format-patch -1 -o ..
 595        ) &&
 596        case "$filename" in
 597        ../0*)
 598                ;; # ok
 599        *)
 600                echo "Oops? $filename"
 601                false
 602                ;;
 603        esac &&
 604        basename=$(expr "$filename" : ".*/\(.*\)") &&
 605        test -f "sub/$basename"
 606'
 607
 608test_expect_success 'format-patch from a subdirectory (3)' '
 609        rm -f 0* &&
 610        filename=$(
 611                rm -rf sub &&
 612                mkdir -p sub/dir &&
 613                cd sub/dir &&
 614                git format-patch -1 -o "$TRASH_DIRECTORY"
 615        ) &&
 616        basename=$(expr "$filename" : ".*/\(.*\)") &&
 617        test -f "$basename"
 618'
 619
 620test_expect_success 'format-patch --in-reply-to' '
 621        git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
 622        grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
 623        grep "^References: <baz@foo.bar>" patch8
 624'
 625
 626test_expect_success 'format-patch --signoff' '
 627        git format-patch -1 --signoff --stdout |
 628        grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
 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