t / t4014-format-patch.shon commit clean: replace match_pathspec() with dir_path_match() (05b8502)
   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 (ascii)' '
 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_failure 'additional command line cc (rfc822)' '
 154
 155        git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
 156        git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
 157        grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
 158        grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
 159'
 160
 161test_expect_success 'command line headers' '
 162
 163        git config --unset-all format.headers &&
 164        git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
 165        grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
 166'
 167
 168test_expect_success 'configuration headers and command line headers' '
 169
 170        git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
 171        git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
 172        grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
 173        grep "^ *S E Cipient <scipient@example.com>\$" patch7
 174'
 175
 176test_expect_success 'command line To: header (ascii)' '
 177
 178        git config --unset-all format.headers &&
 179        git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
 180        grep "^To: R E Cipient <rcipient@example.com>\$" patch8
 181'
 182
 183test_expect_failure 'command line To: header (rfc822)' '
 184
 185        git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
 186        grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
 187'
 188
 189test_expect_failure 'command line To: header (rfc2047)' '
 190
 191        git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
 192        grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
 193'
 194
 195test_expect_success 'configuration To: header (ascii)' '
 196
 197        git config format.to "R E Cipient <rcipient@example.com>" &&
 198        git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
 199        grep "^To: R E Cipient <rcipient@example.com>\$" patch9
 200'
 201
 202test_expect_failure 'configuration To: header (rfc822)' '
 203
 204        git config format.to "R. E. Cipient <rcipient@example.com>" &&
 205        git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
 206        grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
 207'
 208
 209test_expect_failure 'configuration To: header (rfc2047)' '
 210
 211        git config format.to "R Ä Cipient <rcipient@example.com>" &&
 212        git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
 213        grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
 214'
 215
 216# check_patch <patch>: Verify that <patch> looks like a half-sane
 217# patch email to avoid a false positive with !grep
 218check_patch () {
 219        grep -e "^From:" "$1" &&
 220        grep -e "^Date:" "$1" &&
 221        grep -e "^Subject:" "$1"
 222}
 223
 224test_expect_success '--no-to overrides config.to' '
 225
 226        git config --replace-all format.to \
 227                "R E Cipient <rcipient@example.com>" &&
 228        git format-patch --no-to --stdout master..side |
 229        sed -e "/^\$/q" >patch10 &&
 230        check_patch patch10 &&
 231        ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
 232'
 233
 234test_expect_success '--no-to and --to replaces config.to' '
 235
 236        git config --replace-all format.to \
 237                "Someone <someone@out.there>" &&
 238        git format-patch --no-to --to="Someone Else <else@out.there>" \
 239                --stdout master..side |
 240        sed -e "/^\$/q" >patch11 &&
 241        check_patch patch11 &&
 242        ! grep "^To: Someone <someone@out.there>\$" patch11 &&
 243        grep "^To: Someone Else <else@out.there>\$" patch11
 244'
 245
 246test_expect_success '--no-cc overrides config.cc' '
 247
 248        git config --replace-all format.cc \
 249                "C E Cipient <rcipient@example.com>" &&
 250        git format-patch --no-cc --stdout master..side |
 251        sed -e "/^\$/q" >patch12 &&
 252        check_patch patch12 &&
 253        ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
 254'
 255
 256test_expect_success '--no-add-header overrides config.headers' '
 257
 258        git config --replace-all format.headers \
 259                "Header1: B E Cipient <rcipient@example.com>" &&
 260        git format-patch --no-add-header --stdout master..side |
 261        sed -e "/^\$/q" >patch13 &&
 262        check_patch patch13 &&
 263        ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
 264'
 265
 266test_expect_success 'multiple files' '
 267
 268        rm -rf patches/ &&
 269        git checkout side &&
 270        git format-patch -o patches/ master &&
 271        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
 272'
 273
 274test_expect_success 'reroll count' '
 275        rm -fr patches &&
 276        git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
 277        ! grep -v "^patches/v4-000[0-3]-" list &&
 278        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 279        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 280'
 281
 282test_expect_success 'reroll count (-v)' '
 283        rm -fr patches &&
 284        git format-patch -o patches --cover-letter -v4 master..side >list &&
 285        ! grep -v "^patches/v4-000[0-3]-" list &&
 286        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 287        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 288'
 289
 290check_threading () {
 291        expect="$1" &&
 292        shift &&
 293        (git format-patch --stdout "$@"; echo $? > status.out) |
 294        # Prints everything between the Message-ID and In-Reply-To,
 295        # and replaces all Message-ID-lookalikes by a sequence number
 296        perl -ne '
 297                if (/^(message-id|references|in-reply-to)/i) {
 298                        $printing = 1;
 299                } elsif (/^\S/) {
 300                        $printing = 0;
 301                }
 302                if ($printing) {
 303                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 304                        for $k (keys %h) {s/$k/$h{$k}/};
 305                        print;
 306                }
 307                print "---\n" if /^From /i;
 308        ' > actual &&
 309        test 0 = "$(cat status.out)" &&
 310        test_cmp "$expect" actual
 311}
 312
 313cat >> expect.no-threading <<EOF
 314---
 315---
 316---
 317EOF
 318
 319test_expect_success 'no threading' '
 320        git checkout side &&
 321        check_threading expect.no-threading master
 322'
 323
 324cat > expect.thread <<EOF
 325---
 326Message-Id: <0>
 327---
 328Message-Id: <1>
 329In-Reply-To: <0>
 330References: <0>
 331---
 332Message-Id: <2>
 333In-Reply-To: <0>
 334References: <0>
 335EOF
 336
 337test_expect_success 'thread' '
 338        check_threading expect.thread --thread master
 339'
 340
 341cat > expect.in-reply-to <<EOF
 342---
 343Message-Id: <0>
 344In-Reply-To: <1>
 345References: <1>
 346---
 347Message-Id: <2>
 348In-Reply-To: <1>
 349References: <1>
 350---
 351Message-Id: <3>
 352In-Reply-To: <1>
 353References: <1>
 354EOF
 355
 356test_expect_success 'thread in-reply-to' '
 357        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 358                --thread master
 359'
 360
 361cat > expect.cover-letter <<EOF
 362---
 363Message-Id: <0>
 364---
 365Message-Id: <1>
 366In-Reply-To: <0>
 367References: <0>
 368---
 369Message-Id: <2>
 370In-Reply-To: <0>
 371References: <0>
 372---
 373Message-Id: <3>
 374In-Reply-To: <0>
 375References: <0>
 376EOF
 377
 378test_expect_success 'thread cover-letter' '
 379        check_threading expect.cover-letter --cover-letter --thread master
 380'
 381
 382cat > expect.cl-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: <0>
 395References: <1>
 396        <0>
 397---
 398Message-Id: <4>
 399In-Reply-To: <0>
 400References: <1>
 401        <0>
 402EOF
 403
 404test_expect_success 'thread cover-letter in-reply-to' '
 405        check_threading expect.cl-irt --cover-letter \
 406                --in-reply-to="<test.message>" --thread master
 407'
 408
 409test_expect_success 'thread explicit shallow' '
 410        check_threading expect.cl-irt --cover-letter \
 411                --in-reply-to="<test.message>" --thread=shallow master
 412'
 413
 414cat > expect.deep <<EOF
 415---
 416Message-Id: <0>
 417---
 418Message-Id: <1>
 419In-Reply-To: <0>
 420References: <0>
 421---
 422Message-Id: <2>
 423In-Reply-To: <1>
 424References: <0>
 425        <1>
 426EOF
 427
 428test_expect_success 'thread deep' '
 429        check_threading expect.deep --thread=deep master
 430'
 431
 432cat > expect.deep-irt <<EOF
 433---
 434Message-Id: <0>
 435In-Reply-To: <1>
 436References: <1>
 437---
 438Message-Id: <2>
 439In-Reply-To: <0>
 440References: <1>
 441        <0>
 442---
 443Message-Id: <3>
 444In-Reply-To: <2>
 445References: <1>
 446        <0>
 447        <2>
 448EOF
 449
 450test_expect_success 'thread deep in-reply-to' '
 451        check_threading expect.deep-irt  --thread=deep \
 452                --in-reply-to="<test.message>" master
 453'
 454
 455cat > expect.deep-cl <<EOF
 456---
 457Message-Id: <0>
 458---
 459Message-Id: <1>
 460In-Reply-To: <0>
 461References: <0>
 462---
 463Message-Id: <2>
 464In-Reply-To: <1>
 465References: <0>
 466        <1>
 467---
 468Message-Id: <3>
 469In-Reply-To: <2>
 470References: <0>
 471        <1>
 472        <2>
 473EOF
 474
 475test_expect_success 'thread deep cover-letter' '
 476        check_threading expect.deep-cl --cover-letter --thread=deep master
 477'
 478
 479cat > expect.deep-cl-irt <<EOF
 480---
 481Message-Id: <0>
 482In-Reply-To: <1>
 483References: <1>
 484---
 485Message-Id: <2>
 486In-Reply-To: <0>
 487References: <1>
 488        <0>
 489---
 490Message-Id: <3>
 491In-Reply-To: <2>
 492References: <1>
 493        <0>
 494        <2>
 495---
 496Message-Id: <4>
 497In-Reply-To: <3>
 498References: <1>
 499        <0>
 500        <2>
 501        <3>
 502EOF
 503
 504test_expect_success 'thread deep cover-letter in-reply-to' '
 505        check_threading expect.deep-cl-irt --cover-letter \
 506                --in-reply-to="<test.message>" --thread=deep master
 507'
 508
 509test_expect_success 'thread via config' '
 510        test_config format.thread true &&
 511        check_threading expect.thread master
 512'
 513
 514test_expect_success 'thread deep via config' '
 515        test_config format.thread deep &&
 516        check_threading expect.deep master
 517'
 518
 519test_expect_success 'thread config + override' '
 520        test_config format.thread deep &&
 521        check_threading expect.thread --thread master
 522'
 523
 524test_expect_success 'thread config + --no-thread' '
 525        test_config format.thread deep &&
 526        check_threading expect.no-threading --no-thread master
 527'
 528
 529test_expect_success 'excessive subject' '
 530
 531        rm -rf patches/ &&
 532        git checkout side &&
 533        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 534        git update-index file &&
 535        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." &&
 536        git format-patch -o patches/ master..side &&
 537        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 538'
 539
 540test_expect_success 'cover-letter inherits diff options' '
 541
 542        git mv file foo &&
 543        git commit -m foo &&
 544        git format-patch --cover-letter -1 &&
 545        check_patch 0000-cover-letter.patch &&
 546        ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
 547        git format-patch --cover-letter -1 -M &&
 548        grep "file => foo .* 0 *\$" 0000-cover-letter.patch
 549
 550'
 551
 552cat > expect << EOF
 553  This is an excessively long subject line for a message due to the
 554    habit some projects have of not having a short, one-line subject at
 555    the start of the commit message, but rather sticking a whole
 556    paragraph right at the start as the only thing in the commit
 557    message. It had better not become the filename for the patch.
 558  foo
 559
 560EOF
 561
 562test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 563
 564        git format-patch --cover-letter -2 &&
 565        sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
 566        test_cmp expect output
 567
 568'
 569
 570cat > expect << EOF
 571index 40f36c6..2dc5c23 100644
 572--- a/file
 573+++ b/file
 574@@ -13,4 +13,20 @@ C
 575 10
 576 D
 577 E
 578 F
 579+5
 580EOF
 581
 582test_expect_success 'format-patch respects -U' '
 583
 584        git format-patch -U4 -2 &&
 585        sed -e "1,/^diff/d" -e "/^+5/q" \
 586                <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
 587                >output &&
 588        test_cmp expect output
 589
 590'
 591
 592cat > expect << EOF
 593
 594diff --git a/file b/file
 595index 40f36c6..2dc5c23 100644
 596--- a/file
 597+++ b/file
 598@@ -14,3 +14,19 @@ C
 599 D
 600 E
 601 F
 602+5
 603EOF
 604
 605test_expect_success 'format-patch -p suppresses stat' '
 606
 607        git format-patch -p -2 &&
 608        sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 609        test_cmp expect output
 610
 611'
 612
 613test_expect_success 'format-patch from a subdirectory (1)' '
 614        filename=$(
 615                rm -rf sub &&
 616                mkdir -p sub/dir &&
 617                cd sub/dir &&
 618                git format-patch -1
 619        ) &&
 620        case "$filename" in
 621        0*)
 622                ;; # ok
 623        *)
 624                echo "Oops? $filename"
 625                false
 626                ;;
 627        esac &&
 628        test -f "$filename"
 629'
 630
 631test_expect_success 'format-patch from a subdirectory (2)' '
 632        filename=$(
 633                rm -rf sub &&
 634                mkdir -p sub/dir &&
 635                cd sub/dir &&
 636                git format-patch -1 -o ..
 637        ) &&
 638        case "$filename" in
 639        ../0*)
 640                ;; # ok
 641        *)
 642                echo "Oops? $filename"
 643                false
 644                ;;
 645        esac &&
 646        basename=$(expr "$filename" : ".*/\(.*\)") &&
 647        test -f "sub/$basename"
 648'
 649
 650test_expect_success 'format-patch from a subdirectory (3)' '
 651        rm -f 0* &&
 652        filename=$(
 653                rm -rf sub &&
 654                mkdir -p sub/dir &&
 655                cd sub/dir &&
 656                git format-patch -1 -o "$TRASH_DIRECTORY"
 657        ) &&
 658        basename=$(expr "$filename" : ".*/\(.*\)") &&
 659        test -f "$basename"
 660'
 661
 662test_expect_success 'format-patch --in-reply-to' '
 663        git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
 664        grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
 665        grep "^References: <baz@foo.bar>" patch8
 666'
 667
 668test_expect_success 'format-patch --signoff' '
 669        git format-patch -1 --signoff --stdout >out &&
 670        grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
 671'
 672
 673test_expect_success 'format-patch --notes --signoff' '
 674        git notes --ref test add -m "test message" HEAD &&
 675        git format-patch -1 --signoff --stdout --notes=test >out &&
 676        # Three dashes must come after S-o-b
 677        ! sed "/^Signed-off-by: /q" out | grep "test message" &&
 678        sed "1,/^Signed-off-by: /d" out | grep "test message" &&
 679        # Notes message must come after three dashes
 680        ! sed "/^---$/q" out | grep "test message" &&
 681        sed "1,/^---$/d" out | grep "test message"
 682'
 683
 684echo "fatal: --name-only does not make sense" > expect.name-only
 685echo "fatal: --name-status does not make sense" > expect.name-status
 686echo "fatal: --check does not make sense" > expect.check
 687
 688test_expect_success 'options no longer allowed for format-patch' '
 689        test_must_fail git format-patch --name-only 2> output &&
 690        test_i18ncmp expect.name-only output &&
 691        test_must_fail git format-patch --name-status 2> output &&
 692        test_i18ncmp expect.name-status output &&
 693        test_must_fail git format-patch --check 2> output &&
 694        test_i18ncmp expect.check output'
 695
 696test_expect_success 'format-patch --numstat should produce a patch' '
 697        git format-patch --numstat --stdout master..side > output &&
 698        test 6 = $(grep "^diff --git a/" output | wc -l)'
 699
 700test_expect_success 'format-patch -- <path>' '
 701        git format-patch master..side -- file 2>error &&
 702        ! grep "Use .--" error
 703'
 704
 705test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
 706        git format-patch --ignore-if-in-upstream HEAD
 707'
 708
 709test_expect_success 'format-patch --signature' '
 710        git format-patch --stdout --signature="my sig" -1 >output &&
 711        grep "my sig" output
 712'
 713
 714test_expect_success 'format-patch with format.signature config' '
 715        git config format.signature "config sig" &&
 716        git format-patch --stdout -1 >output &&
 717        grep "config sig" output
 718'
 719
 720test_expect_success 'format-patch --signature overrides format.signature' '
 721        git config format.signature "config sig" &&
 722        git format-patch --stdout --signature="overrides" -1 >output &&
 723        ! grep "config sig" output &&
 724        grep "overrides" output
 725'
 726
 727test_expect_success 'format-patch --no-signature ignores format.signature' '
 728        git config format.signature "config sig" &&
 729        git format-patch --stdout --signature="my sig" --no-signature \
 730                -1 >output &&
 731        check_patch output &&
 732        ! grep "config sig" output &&
 733        ! grep "my sig" output &&
 734        ! grep "^-- \$" output
 735'
 736
 737test_expect_success 'format-patch --signature --cover-letter' '
 738        git config --unset-all format.signature &&
 739        git format-patch --stdout --signature="my sig" --cover-letter \
 740                -1 >output &&
 741        grep "my sig" output &&
 742        test 2 = $(grep "my sig" output | wc -l)
 743'
 744
 745test_expect_success 'format.signature="" suppresses signatures' '
 746        git config format.signature "" &&
 747        git format-patch --stdout -1 >output &&
 748        check_patch output &&
 749        ! grep "^-- \$" output
 750'
 751
 752test_expect_success 'format-patch --no-signature suppresses signatures' '
 753        git config --unset-all format.signature &&
 754        git format-patch --stdout --no-signature -1 >output &&
 755        check_patch output &&
 756        ! grep "^-- \$" output
 757'
 758
 759test_expect_success 'format-patch --signature="" suppresses signatures' '
 760        git format-patch --stdout --signature="" -1 >output &&
 761        check_patch output &&
 762        ! grep "^-- \$" output
 763'
 764
 765test_expect_success TTY 'format-patch --stdout paginates' '
 766        rm -f pager_used &&
 767        (
 768                GIT_PAGER="wc >pager_used" &&
 769                export GIT_PAGER &&
 770                test_terminal git format-patch --stdout --all
 771        ) &&
 772        test_path_is_file pager_used
 773'
 774
 775 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
 776        rm -f pager_used &&
 777        (
 778                GIT_PAGER="wc >pager_used" &&
 779                export GIT_PAGER &&
 780                test_terminal git --no-pager format-patch --stdout --all &&
 781                test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
 782        ) &&
 783        test_path_is_missing pager_used &&
 784        test_path_is_missing .git/pager_used
 785'
 786
 787test_expect_success 'format-patch handles multi-line subjects' '
 788        rm -rf patches/ &&
 789        echo content >>file &&
 790        for i in one two three; do echo $i; done >msg &&
 791        git add file &&
 792        git commit -F msg &&
 793        git format-patch -o patches -1 &&
 794        grep ^Subject: patches/0001-one.patch >actual &&
 795        echo "Subject: [PATCH] one two three" >expect &&
 796        test_cmp expect actual
 797'
 798
 799test_expect_success 'format-patch handles multi-line encoded subjects' '
 800        rm -rf patches/ &&
 801        echo content >>file &&
 802        for i in en två tre; do echo $i; done >msg &&
 803        git add file &&
 804        git commit -F msg &&
 805        git format-patch -o patches -1 &&
 806        grep ^Subject: patches/0001-en.patch >actual &&
 807        echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
 808        test_cmp expect actual
 809'
 810
 811M8="foo bar "
 812M64=$M8$M8$M8$M8$M8$M8$M8$M8
 813M512=$M64$M64$M64$M64$M64$M64$M64$M64
 814cat >expect <<'EOF'
 815Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 816 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 817 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 818 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 819 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
 820 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 821 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
 822EOF
 823test_expect_success 'format-patch wraps extremely long subject (ascii)' '
 824        echo content >>file &&
 825        git add file &&
 826        git commit -m "$M512" &&
 827        git format-patch --stdout -1 >patch &&
 828        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 829        test_cmp expect subject
 830'
 831
 832M8="föö bar "
 833M64=$M8$M8$M8$M8$M8$M8$M8$M8
 834M512=$M64$M64$M64$M64$M64$M64$M64$M64
 835cat >expect <<'EOF'
 836Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 837 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 838 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 839 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 840 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 841 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 842 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 843 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 844 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 845 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 846 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 847 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 848 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 849 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 850 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 851 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 852 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 853 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 854 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 855 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 856 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 857 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 858 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 859 =?UTF-8?q?bar?=
 860EOF
 861test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
 862        rm -rf patches/ &&
 863        echo content >>file &&
 864        git add file &&
 865        git commit -m "$M512" &&
 866        git format-patch --stdout -1 >patch &&
 867        sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
 868        test_cmp expect subject
 869'
 870
 871check_author() {
 872        echo content >>file &&
 873        git add file &&
 874        GIT_AUTHOR_NAME=$1 git commit -m author-check &&
 875        git format-patch --stdout -1 >patch &&
 876        sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
 877        test_cmp expect actual
 878}
 879
 880cat >expect <<'EOF'
 881From: "Foo B. Bar" <author@example.com>
 882EOF
 883test_expect_success 'format-patch quotes dot in from-headers' '
 884        check_author "Foo B. Bar"
 885'
 886
 887cat >expect <<'EOF'
 888From: "Foo \"The Baz\" Bar" <author@example.com>
 889EOF
 890test_expect_success 'format-patch quotes double-quote in from-headers' '
 891        check_author "Foo \"The Baz\" Bar"
 892'
 893
 894cat >expect <<'EOF'
 895From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
 896EOF
 897test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
 898        check_author "Föo Bar"
 899'
 900
 901cat >expect <<'EOF'
 902From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
 903EOF
 904test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
 905        check_author "Föo B. Bar"
 906'
 907
 908cat >expect <<EOF
 909From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
 910 <author@example.com>
 911EOF
 912test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
 913        check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
 914'
 915
 916cat >expect <<'EOF'
 917From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
 918 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
 919 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
 920EOF
 921test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
 922        check_author "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
 923'
 924
 925cat >expect <<'EOF'
 926From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
 927 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
 928 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
 929EOF
 930test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
 931        check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
 932'
 933
 934cat >expect <<'EOF'
 935From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
 936 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
 937 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
 938 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
 939 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
 940EOF
 941test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
 942        check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
 943'
 944
 945cat >expect <<'EOF'
 946Subject: header with . in it
 947EOF
 948test_expect_success 'subject lines do not have 822 atom-quoting' '
 949        echo content >>file &&
 950        git add file &&
 951        git commit -m "header with . in it" &&
 952        git format-patch -k -1 --stdout >patch &&
 953        grep ^Subject: patch >actual &&
 954        test_cmp expect actual
 955'
 956
 957cat >expect <<'EOF'
 958Subject: [PREFIX 1/1] header with . in it
 959EOF
 960test_expect_success 'subject prefixes have space prepended' '
 961        git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
 962        grep ^Subject: patch >actual &&
 963        test_cmp expect actual
 964'
 965
 966cat >expect <<'EOF'
 967Subject: [1/1] header with . in it
 968EOF
 969test_expect_success 'empty subject prefix does not have extra space' '
 970        git format-patch -n -1 --stdout --subject-prefix= >patch &&
 971        grep ^Subject: patch >actual &&
 972        test_cmp expect actual
 973'
 974
 975test_expect_success '--from=ident notices bogus ident' '
 976        test_must_fail git format-patch -1 --stdout --from=foo >patch
 977'
 978
 979test_expect_success '--from=ident replaces author' '
 980        git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
 981        cat >expect <<-\EOF &&
 982        From: Me <me@example.com>
 983
 984        From: A U Thor <author@example.com>
 985
 986        EOF
 987        sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
 988        test_cmp expect patch.head
 989'
 990
 991test_expect_success '--from uses committer ident' '
 992        git format-patch -1 --stdout --from >patch &&
 993        cat >expect <<-\EOF &&
 994        From: C O Mitter <committer@example.com>
 995
 996        From: A U Thor <author@example.com>
 997
 998        EOF
 999        sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1000        test_cmp expect patch.head
1001'
1002
1003test_expect_success '--from omits redundant in-body header' '
1004        git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1005        cat >expect <<-\EOF &&
1006        From: A U Thor <author@example.com>
1007
1008        EOF
1009        sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1010        test_cmp expect patch.head
1011'
1012
1013test_expect_success 'in-body headers trigger content encoding' '
1014        GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1015        test_when_finished "git reset --hard HEAD^" &&
1016        git format-patch -1 --stdout --from >patch &&
1017        cat >expect <<-\EOF &&
1018        From: C O Mitter <committer@example.com>
1019        Content-Type: text/plain; charset=UTF-8
1020
1021        From: éxötìc <author@example.com>
1022
1023        EOF
1024        sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1025        test_cmp expect patch.head
1026'
1027
1028append_signoff()
1029{
1030        C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1031        git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1032        sed -n -e "1,/^---$/p" append_signoff.patch |
1033                egrep -n "^Subject|Sign|^$"
1034}
1035
1036test_expect_success 'signoff: commit with no body' '
1037        append_signoff </dev/null >actual &&
1038        cat <<\EOF | sed "s/EOL$//" >expected &&
10394:Subject: [PATCH] EOL
10408:
10419:Signed-off-by: C O Mitter <committer@example.com>
1042EOF
1043        test_cmp expected actual
1044'
1045
1046test_expect_success 'signoff: commit with only subject' '
1047        echo subject | append_signoff >actual &&
1048        cat >expected <<\EOF &&
10494:Subject: [PATCH] subject
10508:
10519:Signed-off-by: C O Mitter <committer@example.com>
1052EOF
1053        test_cmp expected actual
1054'
1055
1056test_expect_success 'signoff: commit with only subject that does not end with NL' '
1057        printf subject | append_signoff >actual &&
1058        cat >expected <<\EOF &&
10594:Subject: [PATCH] subject
10608:
10619:Signed-off-by: C O Mitter <committer@example.com>
1062EOF
1063        test_cmp expected actual
1064'
1065
1066test_expect_success 'signoff: no existing signoffs' '
1067        append_signoff <<\EOF >actual &&
1068subject
1069
1070body
1071EOF
1072        cat >expected <<\EOF &&
10734:Subject: [PATCH] subject
10748:
107510:
107611:Signed-off-by: C O Mitter <committer@example.com>
1077EOF
1078        test_cmp expected actual
1079'
1080
1081test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1082        printf "subject\n\nbody" | append_signoff >actual &&
1083        cat >expected <<\EOF &&
10844:Subject: [PATCH] subject
10858:
108610:
108711:Signed-off-by: C O Mitter <committer@example.com>
1088EOF
1089        test_cmp expected actual
1090'
1091
1092test_expect_success 'signoff: some random signoff' '
1093        append_signoff <<\EOF >actual &&
1094subject
1095
1096body
1097
1098Signed-off-by: my@house
1099EOF
1100        cat >expected <<\EOF &&
11014:Subject: [PATCH] subject
11028:
110310:
110411:Signed-off-by: my@house
110512:Signed-off-by: C O Mitter <committer@example.com>
1106EOF
1107        test_cmp expected actual
1108'
1109
1110test_expect_success 'signoff: misc conforming footer elements' '
1111        append_signoff <<\EOF >actual &&
1112subject
1113
1114body
1115
1116Signed-off-by: my@house
1117(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1118Tested-by: Some One <someone@example.com>
1119Bug: 1234
1120EOF
1121        cat >expected <<\EOF &&
11224:Subject: [PATCH] subject
11238:
112410:
112511:Signed-off-by: my@house
112615:Signed-off-by: C O Mitter <committer@example.com>
1127EOF
1128        test_cmp expected actual
1129'
1130
1131test_expect_success 'signoff: some random signoff-alike' '
1132        append_signoff <<\EOF >actual &&
1133subject
1134
1135body
1136Fooled-by-me: my@house
1137EOF
1138        cat >expected <<\EOF &&
11394:Subject: [PATCH] subject
11408:
114111:
114212:Signed-off-by: C O Mitter <committer@example.com>
1143EOF
1144        test_cmp expected actual
1145'
1146
1147test_expect_success 'signoff: not really a signoff' '
1148        append_signoff <<\EOF >actual &&
1149subject
1150
1151I want to mention about Signed-off-by: here.
1152EOF
1153        cat >expected <<\EOF &&
11544:Subject: [PATCH] subject
11558:
11569:I want to mention about Signed-off-by: here.
115710:
115811:Signed-off-by: C O Mitter <committer@example.com>
1159EOF
1160        test_cmp expected actual
1161'
1162
1163test_expect_success 'signoff: not really a signoff (2)' '
1164        append_signoff <<\EOF >actual &&
1165subject
1166
1167My unfortunate
1168Signed-off-by: example happens to be wrapped here.
1169EOF
1170        cat >expected <<\EOF &&
11714:Subject: [PATCH] subject
11728:
117310:Signed-off-by: example happens to be wrapped here.
117411:
117512:Signed-off-by: C O Mitter <committer@example.com>
1176EOF
1177        test_cmp expected actual
1178'
1179
1180test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1181        append_signoff <<\EOF >actual &&
1182subject
1183
1184Signed-off-by: my@house
1185Signed-off-by: your@house
1186
1187A lot of houses.
1188EOF
1189        cat >expected <<\EOF &&
11904:Subject: [PATCH] subject
11918:
11929:Signed-off-by: my@house
119310:Signed-off-by: your@house
119411:
119513:
119614:Signed-off-by: C O Mitter <committer@example.com>
1197EOF
1198        test_cmp expected actual
1199'
1200
1201test_expect_success 'signoff: the same signoff at the end' '
1202        append_signoff <<\EOF >actual &&
1203subject
1204
1205body
1206
1207Signed-off-by: C O Mitter <committer@example.com>
1208EOF
1209        cat >expected <<\EOF &&
12104:Subject: [PATCH] subject
12118:
121210:
121311:Signed-off-by: C O Mitter <committer@example.com>
1214EOF
1215        test_cmp expected actual
1216'
1217
1218test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1219        printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1220                append_signoff >actual &&
1221        cat >expected <<\EOF &&
12224:Subject: [PATCH] subject
12238:
12249:Signed-off-by: C O Mitter <committer@example.com>
1225EOF
1226        test_cmp expected actual
1227'
1228
1229test_expect_success 'signoff: the same signoff NOT at the end' '
1230        append_signoff <<\EOF >actual &&
1231subject
1232
1233body
1234
1235Signed-off-by: C O Mitter <committer@example.com>
1236Signed-off-by: my@house
1237EOF
1238        cat >expected <<\EOF &&
12394:Subject: [PATCH] subject
12408:
124110:
124211:Signed-off-by: C O Mitter <committer@example.com>
124312:Signed-off-by: my@house
1244EOF
1245        test_cmp expected actual
1246'
1247
1248test_expect_success 'signoff: detect garbage in non-conforming footer' '
1249        append_signoff <<\EOF >actual &&
1250subject
1251
1252body
1253
1254Tested-by: my@house
1255Some Trash
1256Signed-off-by: C O Mitter <committer@example.com>
1257EOF
1258        cat >expected <<\EOF &&
12594:Subject: [PATCH] subject
12608:
126110:
126213:Signed-off-by: C O Mitter <committer@example.com>
126314:
126415:Signed-off-by: C O Mitter <committer@example.com>
1265EOF
1266        test_cmp expected actual
1267'
1268
1269test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1270        append_signoff <<\EOF >actual &&
1271subject
1272
1273body
1274
1275Reviewed-id: Noone
1276Tested-by: my@house
1277Change-id: Ideadbeef
1278Signed-off-by: C O Mitter <committer@example.com>
1279Bug: 1234
1280EOF
1281        cat >expected <<\EOF &&
12824:Subject: [PATCH] subject
12838:
128410:
128514:Signed-off-by: C O Mitter <committer@example.com>
1286EOF
1287        test_cmp expected actual
1288'
1289
1290test_expect_success 'format patch ignores color.ui' '
1291        test_unconfig color.ui &&
1292        git format-patch --stdout -1 >expect &&
1293        test_config color.ui always &&
1294        git format-patch --stdout -1 >actual &&
1295        test_cmp expect actual
1296'
1297
1298test_expect_success 'cover letter using branch description (1)' '
1299        git checkout rebuild-1 &&
1300        test_config branch.rebuild-1.description hello &&
1301        git format-patch --stdout --cover-letter master >actual &&
1302        grep hello actual >/dev/null
1303'
1304
1305test_expect_success 'cover letter using branch description (2)' '
1306        git checkout rebuild-1 &&
1307        test_config branch.rebuild-1.description hello &&
1308        git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1309        grep hello actual >/dev/null
1310'
1311
1312test_expect_success 'cover letter using branch description (3)' '
1313        git checkout rebuild-1 &&
1314        test_config branch.rebuild-1.description hello &&
1315        git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1316        grep hello actual >/dev/null
1317'
1318
1319test_expect_success 'cover letter using branch description (4)' '
1320        git checkout rebuild-1 &&
1321        test_config branch.rebuild-1.description hello &&
1322        git format-patch --stdout --cover-letter master.. >actual &&
1323        grep hello actual >/dev/null
1324'
1325
1326test_expect_success 'cover letter using branch description (5)' '
1327        git checkout rebuild-1 &&
1328        test_config branch.rebuild-1.description hello &&
1329        git format-patch --stdout --cover-letter -2 HEAD >actual &&
1330        grep hello actual >/dev/null
1331'
1332
1333test_expect_success 'cover letter using branch description (6)' '
1334        git checkout rebuild-1 &&
1335        test_config branch.rebuild-1.description hello &&
1336        git format-patch --stdout --cover-letter -2 >actual &&
1337        grep hello actual >/dev/null
1338'
1339
1340test_expect_success 'cover letter with nothing' '
1341        git format-patch --stdout --cover-letter >actual &&
1342        test_line_count = 0 actual
1343'
1344
1345test_expect_success 'cover letter auto' '
1346        mkdir -p tmp &&
1347        test_when_finished "rm -rf tmp;
1348                git config --unset format.coverletter" &&
1349
1350        git config format.coverletter auto &&
1351        git format-patch -o tmp -1 >list &&
1352        test_line_count = 1 list &&
1353        git format-patch -o tmp -2 >list &&
1354        test_line_count = 3 list
1355'
1356
1357test_expect_success 'cover letter auto user override' '
1358        mkdir -p tmp &&
1359        test_when_finished "rm -rf tmp;
1360                git config --unset format.coverletter" &&
1361
1362        git config format.coverletter auto &&
1363        git format-patch -o tmp --cover-letter -1 >list &&
1364        test_line_count = 2 list &&
1365        git format-patch -o tmp --cover-letter -2 >list &&
1366        test_line_count = 3 list &&
1367        git format-patch -o tmp --no-cover-letter -1 >list &&
1368        test_line_count = 1 list &&
1369        git format-patch -o tmp --no-cover-letter -2 >list &&
1370        test_line_count = 2 list
1371'
1372
1373test_done