t / t4014-format-patch.shon commit Merge branch 'jk/fast-import-history-bugfix' (991fd97)
   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        for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
  13        cat file >elif &&
  14        git add file elif &&
  15        test_tick &&
  16        git commit -m Initial &&
  17        git checkout -b side &&
  18
  19        for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
  20        test_chmod +x elif &&
  21        test_tick &&
  22        git commit -m "Side changes #1" &&
  23
  24        for i in D E F; do echo "$i"; done >>file &&
  25        git update-index file &&
  26        test_tick &&
  27        git commit -m "Side changes #2" &&
  28        git tag C2 &&
  29
  30        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
  31        git update-index file &&
  32        test_tick &&
  33        git commit -m "Side changes #3 with \\n backslash-n in it." &&
  34
  35        git checkout master &&
  36        git diff-tree -p C2 >patch &&
  37        git apply --index <patch &&
  38        test_tick &&
  39        git commit -m "Master accepts moral equivalent of #2" &&
  40
  41        git checkout side &&
  42        git checkout -b patchid &&
  43        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
  44        for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
  45        for i in 8 9 10; do echo "$i"; done >file &&
  46        git add file file2 file3 &&
  47        test_tick &&
  48        git commit -m "patchid 1" &&
  49        for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
  50        for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
  51        git add file2 file3 &&
  52        test_tick &&
  53        git commit -m "patchid 2" &&
  54        for i in 10 5 6; do echo "$i"; done >file &&
  55        git add file &&
  56        test_tick &&
  57        git commit -m "patchid 3" &&
  58
  59        git checkout master
  60'
  61
  62test_expect_success 'format-patch --ignore-if-in-upstream' '
  63        git format-patch --stdout master..side >patch0 &&
  64        grep "^From " patch0 >from0 &&
  65        test_line_count = 3 from0
  66'
  67
  68test_expect_success 'format-patch --ignore-if-in-upstream' '
  69        git format-patch --stdout \
  70                --ignore-if-in-upstream master..side >patch1 &&
  71        grep "^From " patch1 >from1 &&
  72        test_line_count = 2 from1
  73'
  74
  75test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
  76        git tag -a v1 -m tag side &&
  77        git tag -a v2 -m tag master &&
  78        git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
  79        grep "^From " patch1 >from1 &&
  80        test_line_count = 2 from1
  81'
  82
  83test_expect_success "format-patch doesn't consider merge commits" '
  84        git checkout -b slave master &&
  85        echo "Another line" >>file &&
  86        test_tick &&
  87        git commit -am "Slave change #1" &&
  88        echo "Yet another line" >>file &&
  89        test_tick &&
  90        git commit -am "Slave change #2" &&
  91        git checkout -b merger master &&
  92        test_tick &&
  93        git merge --no-ff slave &&
  94        git format-patch -3 --stdout >patch &&
  95        grep "^From " patch >from &&
  96        test_line_count = 3 from
  97'
  98
  99test_expect_success 'format-patch result applies' '
 100        git checkout -b rebuild-0 master &&
 101        git am -3 patch0 &&
 102        git rev-list master.. >list &&
 103        test_line_count = 2 list
 104'
 105
 106test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
 107        git checkout -b rebuild-1 master &&
 108        git am -3 patch1 &&
 109        git rev-list master.. >list &&
 110        test_line_count = 2 list
 111'
 112
 113test_expect_success 'commit did not screw up the log message' '
 114        git cat-file commit side >actual &&
 115        grep "^Side .* with .* backslash-n" actual
 116'
 117
 118test_expect_success 'format-patch did not screw up the log message' '
 119        grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
 120        grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
 121'
 122
 123test_expect_success 'replay did not screw up the log message' '
 124        git cat-file commit rebuild-1 >actual &&
 125        grep "^Side .* with .* backslash-n" actual
 126'
 127
 128test_expect_success 'extra headers' '
 129        git config format.headers "To: R E Cipient <rcipient@example.com>
 130" &&
 131        git config --add format.headers "Cc: S E Cipient <scipient@example.com>
 132" &&
 133        git format-patch --stdout master..side >patch2 &&
 134        sed -e "/^\$/q" patch2 >hdrs2 &&
 135        grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
 136        grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
 137'
 138
 139test_expect_success 'extra headers without newlines' '
 140        git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
 141        git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
 142        git format-patch --stdout master..side >patch3 &&
 143        sed -e "/^\$/q" patch3 >hdrs3 &&
 144        grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
 145        grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
 146'
 147
 148test_expect_success 'extra headers with multiple To:s' '
 149        git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
 150        git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
 151        git format-patch --stdout master..side >patch4 &&
 152        sed -e "/^\$/q" patch4 >hdrs4 &&
 153        grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
 154        grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
 155'
 156
 157test_expect_success 'additional command line cc (ascii)' '
 158        git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
 159        git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side >patch5 &&
 160        sed -e "/^\$/q" patch5 >hdrs5 &&
 161        grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
 162        grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
 163'
 164
 165test_expect_failure 'additional command line cc (rfc822)' '
 166        git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
 167        git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side >patch5 &&
 168        sed -e "/^\$/q" patch5 >hdrs5 &&
 169        grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
 170        grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
 171'
 172
 173test_expect_success 'command line headers' '
 174        git config --unset-all format.headers &&
 175        git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side >patch6 &&
 176        sed -e "/^\$/q" patch6 >hdrs6 &&
 177        grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
 178'
 179
 180test_expect_success 'configuration headers and command line headers' '
 181        git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
 182        git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side >patch7 &&
 183        sed -e "/^\$/q" patch7 >hdrs7 &&
 184        grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
 185        grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
 186'
 187
 188test_expect_success 'command line To: header (ascii)' '
 189        git config --unset-all format.headers &&
 190        git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
 191        sed -e "/^\$/q" patch8 >hdrs8 &&
 192        grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
 193'
 194
 195test_expect_failure 'command line To: header (rfc822)' '
 196        git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
 197        sed -e "/^\$/q" patch8 >hdrs8 &&
 198        grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
 199'
 200
 201test_expect_failure 'command line To: header (rfc2047)' '
 202        git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
 203        sed -e "/^\$/q" patch8 >hdrs8 &&
 204        grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
 205'
 206
 207test_expect_success 'configuration To: header (ascii)' '
 208        git config format.to "R E Cipient <rcipient@example.com>" &&
 209        git format-patch --stdout master..side >patch9 &&
 210        sed -e "/^\$/q" patch9 >hdrs9 &&
 211        grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
 212'
 213
 214test_expect_failure 'configuration To: header (rfc822)' '
 215        git config format.to "R. E. Cipient <rcipient@example.com>" &&
 216        git format-patch --stdout master..side >patch9 &&
 217        sed -e "/^\$/q" patch9 >hdrs9 &&
 218        grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
 219'
 220
 221test_expect_failure 'configuration To: header (rfc2047)' '
 222        git config format.to "R Ä Cipient <rcipient@example.com>" &&
 223        git format-patch --stdout master..side >patch9 &&
 224        sed -e "/^\$/q" patch9 >hdrs9 &&
 225        grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
 226'
 227
 228# check_patch <patch>: Verify that <patch> looks like a half-sane
 229# patch email to avoid a false positive with !grep
 230check_patch () {
 231        grep -e "^From:" "$1" &&
 232        grep -e "^Date:" "$1" &&
 233        grep -e "^Subject:" "$1"
 234}
 235
 236test_expect_success 'format.from=false' '
 237        git -c format.from=false format-patch --stdout master..side >patch &&
 238        sed -e "/^\$/q" patch >hdrs &&
 239        check_patch patch &&
 240        ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
 241'
 242
 243test_expect_success 'format.from=true' '
 244        git -c format.from=true format-patch --stdout master..side >patch &&
 245        sed -e "/^\$/q" patch >hdrs &&
 246        check_patch hdrs &&
 247        grep "^From: C O Mitter <committer@example.com>\$" hdrs
 248'
 249
 250test_expect_success 'format.from with address' '
 251        git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side >patch &&
 252        sed -e "/^\$/q" patch >hdrs &&
 253        check_patch hdrs &&
 254        grep "^From: F R Om <from@example.com>\$" hdrs
 255'
 256
 257test_expect_success '--no-from overrides format.from' '
 258        git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side >patch &&
 259        sed -e "/^\$/q" patch >hdrs &&
 260        check_patch hdrs &&
 261        ! grep "^From: F R Om <from@example.com>\$" hdrs
 262'
 263
 264test_expect_success '--from overrides format.from' '
 265        git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side >patch &&
 266        sed -e "/^\$/q" patch >hdrs &&
 267        check_patch hdrs &&
 268        ! grep "^From: F R Om <from@example.com>\$" hdrs
 269'
 270
 271test_expect_success '--no-to overrides config.to' '
 272        git config --replace-all format.to \
 273                "R E Cipient <rcipient@example.com>" &&
 274        git format-patch --no-to --stdout master..side >patch10 &&
 275        sed -e "/^\$/q" patch10 >hdrs10 &&
 276        check_patch hdrs10 &&
 277        ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
 278'
 279
 280test_expect_success '--no-to and --to replaces config.to' '
 281        git config --replace-all format.to \
 282                "Someone <someone@out.there>" &&
 283        git format-patch --no-to --to="Someone Else <else@out.there>" \
 284                --stdout master..side >patch11 &&
 285        sed -e "/^\$/q" patch11 >hdrs11 &&
 286        check_patch hdrs11 &&
 287        ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
 288        grep "^To: Someone Else <else@out.there>\$" hdrs11
 289'
 290
 291test_expect_success '--no-cc overrides config.cc' '
 292        git config --replace-all format.cc \
 293                "C E Cipient <rcipient@example.com>" &&
 294        git format-patch --no-cc --stdout master..side >patch12 &&
 295        sed -e "/^\$/q" patch12 >hdrs12 &&
 296        check_patch hdrs12 &&
 297        ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
 298'
 299
 300test_expect_success '--no-add-header overrides config.headers' '
 301        git config --replace-all format.headers \
 302                "Header1: B E Cipient <rcipient@example.com>" &&
 303        git format-patch --no-add-header --stdout master..side >patch13 &&
 304        sed -e "/^\$/q" patch13 >hdrs13 &&
 305        check_patch hdrs13 &&
 306        ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
 307'
 308
 309test_expect_success 'multiple files' '
 310        rm -rf patches/ &&
 311        git checkout side &&
 312        git format-patch -o patches/ master &&
 313        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
 314'
 315
 316test_expect_success 'reroll count' '
 317        rm -fr patches &&
 318        git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
 319        ! grep -v "^patches/v4-000[0-3]-" list &&
 320        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 321        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 322'
 323
 324test_expect_success 'reroll count (-v)' '
 325        rm -fr patches &&
 326        git format-patch -o patches --cover-letter -v4 master..side >list &&
 327        ! grep -v "^patches/v4-000[0-3]-" list &&
 328        sed -n -e "/^Subject: /p" $(cat list) >subjects &&
 329        ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
 330'
 331
 332check_threading () {
 333        expect="$1" &&
 334        shift &&
 335        git format-patch --stdout "$@" >patch &&
 336        # Prints everything between the Message-ID and In-Reply-To,
 337        # and replaces all Message-ID-lookalikes by a sequence number
 338        perl -ne '
 339                if (/^(message-id|references|in-reply-to)/i) {
 340                        $printing = 1;
 341                } elsif (/^\S/) {
 342                        $printing = 0;
 343                }
 344                if ($printing) {
 345                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 346                        for $k (keys %h) {s/$k/$h{$k}/};
 347                        print;
 348                }
 349                print "---\n" if /^From /i;
 350        ' <patch >actual &&
 351        test_cmp "$expect" actual
 352}
 353
 354cat >>expect.no-threading <<EOF
 355---
 356---
 357---
 358EOF
 359
 360test_expect_success 'no threading' '
 361        git checkout side &&
 362        check_threading expect.no-threading master
 363'
 364
 365cat >expect.thread <<EOF
 366---
 367Message-Id: <0>
 368---
 369Message-Id: <1>
 370In-Reply-To: <0>
 371References: <0>
 372---
 373Message-Id: <2>
 374In-Reply-To: <0>
 375References: <0>
 376EOF
 377
 378test_expect_success 'thread' '
 379        check_threading expect.thread --thread master
 380'
 381
 382cat >expect.in-reply-to <<EOF
 383---
 384Message-Id: <0>
 385In-Reply-To: <1>
 386References: <1>
 387---
 388Message-Id: <2>
 389In-Reply-To: <1>
 390References: <1>
 391---
 392Message-Id: <3>
 393In-Reply-To: <1>
 394References: <1>
 395EOF
 396
 397test_expect_success 'thread in-reply-to' '
 398        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 399                --thread master
 400'
 401
 402cat >expect.cover-letter <<EOF
 403---
 404Message-Id: <0>
 405---
 406Message-Id: <1>
 407In-Reply-To: <0>
 408References: <0>
 409---
 410Message-Id: <2>
 411In-Reply-To: <0>
 412References: <0>
 413---
 414Message-Id: <3>
 415In-Reply-To: <0>
 416References: <0>
 417EOF
 418
 419test_expect_success 'thread cover-letter' '
 420        check_threading expect.cover-letter --cover-letter --thread master
 421'
 422
 423cat >expect.cl-irt <<EOF
 424---
 425Message-Id: <0>
 426In-Reply-To: <1>
 427References: <1>
 428---
 429Message-Id: <2>
 430In-Reply-To: <0>
 431References: <1>
 432        <0>
 433---
 434Message-Id: <3>
 435In-Reply-To: <0>
 436References: <1>
 437        <0>
 438---
 439Message-Id: <4>
 440In-Reply-To: <0>
 441References: <1>
 442        <0>
 443EOF
 444
 445test_expect_success 'thread cover-letter in-reply-to' '
 446        check_threading expect.cl-irt --cover-letter \
 447                --in-reply-to="<test.message>" --thread master
 448'
 449
 450test_expect_success 'thread explicit shallow' '
 451        check_threading expect.cl-irt --cover-letter \
 452                --in-reply-to="<test.message>" --thread=shallow master
 453'
 454
 455cat >expect.deep <<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>
 467EOF
 468
 469test_expect_success 'thread deep' '
 470        check_threading expect.deep --thread=deep master
 471'
 472
 473cat >expect.deep-irt <<EOF
 474---
 475Message-Id: <0>
 476In-Reply-To: <1>
 477References: <1>
 478---
 479Message-Id: <2>
 480In-Reply-To: <0>
 481References: <1>
 482        <0>
 483---
 484Message-Id: <3>
 485In-Reply-To: <2>
 486References: <1>
 487        <0>
 488        <2>
 489EOF
 490
 491test_expect_success 'thread deep in-reply-to' '
 492        check_threading expect.deep-irt  --thread=deep \
 493                --in-reply-to="<test.message>" master
 494'
 495
 496cat >expect.deep-cl <<EOF
 497---
 498Message-Id: <0>
 499---
 500Message-Id: <1>
 501In-Reply-To: <0>
 502References: <0>
 503---
 504Message-Id: <2>
 505In-Reply-To: <1>
 506References: <0>
 507        <1>
 508---
 509Message-Id: <3>
 510In-Reply-To: <2>
 511References: <0>
 512        <1>
 513        <2>
 514EOF
 515
 516test_expect_success 'thread deep cover-letter' '
 517        check_threading expect.deep-cl --cover-letter --thread=deep master
 518'
 519
 520cat >expect.deep-cl-irt <<EOF
 521---
 522Message-Id: <0>
 523In-Reply-To: <1>
 524References: <1>
 525---
 526Message-Id: <2>
 527In-Reply-To: <0>
 528References: <1>
 529        <0>
 530---
 531Message-Id: <3>
 532In-Reply-To: <2>
 533References: <1>
 534        <0>
 535        <2>
 536---
 537Message-Id: <4>
 538In-Reply-To: <3>
 539References: <1>
 540        <0>
 541        <2>
 542        <3>
 543EOF
 544
 545test_expect_success 'thread deep cover-letter in-reply-to' '
 546        check_threading expect.deep-cl-irt --cover-letter \
 547                --in-reply-to="<test.message>" --thread=deep master
 548'
 549
 550test_expect_success 'thread via config' '
 551        test_config format.thread true &&
 552        check_threading expect.thread master
 553'
 554
 555test_expect_success 'thread deep via config' '
 556        test_config format.thread deep &&
 557        check_threading expect.deep master
 558'
 559
 560test_expect_success 'thread config + override' '
 561        test_config format.thread deep &&
 562        check_threading expect.thread --thread master
 563'
 564
 565test_expect_success 'thread config + --no-thread' '
 566        test_config format.thread deep &&
 567        check_threading expect.no-threading --no-thread master
 568'
 569
 570test_expect_success 'excessive subject' '
 571        rm -rf patches/ &&
 572        git checkout side &&
 573        before=$(git hash-object file) &&
 574        before=$(git rev-parse --short $before) &&
 575        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 576        after=$(git hash-object file) &&
 577        after=$(git rev-parse --short $after) &&
 578        git update-index file &&
 579        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." &&
 580        git format-patch -o patches/ master..side &&
 581        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 582'
 583
 584test_expect_success 'failure to write cover-letter aborts gracefully' '
 585        test_when_finished "rmdir 0000-cover-letter.patch" &&
 586        mkdir 0000-cover-letter.patch &&
 587        test_must_fail git format-patch --no-renames --cover-letter -1
 588'
 589
 590test_expect_success 'cover-letter inherits diff options' '
 591        git mv file foo &&
 592        git commit -m foo &&
 593        git format-patch --no-renames --cover-letter -1 &&
 594        check_patch 0000-cover-letter.patch &&
 595        ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
 596        git format-patch --cover-letter -1 -M &&
 597        grep "file => foo .* 0 *\$" 0000-cover-letter.patch
 598'
 599
 600cat >expect <<EOF
 601  This is an excessively long subject line for a message due to the
 602    habit some projects have of not having a short, one-line subject at
 603    the start of the commit message, but rather sticking a whole
 604    paragraph right at the start as the only thing in the commit
 605    message. It had better not become the filename for the patch.
 606  foo
 607
 608EOF
 609
 610test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 611        git format-patch --cover-letter -2 &&
 612        sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
 613        test_cmp expect output
 614'
 615
 616cat >expect <<EOF
 617index $before..$after 100644
 618--- a/file
 619+++ b/file
 620@@ -13,4 +13,20 @@ C
 621 10
 622 D
 623 E
 624 F
 625+5
 626EOF
 627
 628test_expect_success 'format-patch respects -U' '
 629        git format-patch -U4 -2 &&
 630        sed -e "1,/^diff/d" -e "/^+5/q" \
 631                <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
 632                >output &&
 633        test_cmp expect output
 634'
 635
 636cat >expect <<EOF
 637
 638diff --git a/file b/file
 639index $before..$after 100644
 640--- a/file
 641+++ b/file
 642@@ -14,3 +14,19 @@ C
 643 D
 644 E
 645 F
 646+5
 647EOF
 648
 649test_expect_success 'format-patch -p suppresses stat' '
 650        git format-patch -p -2 &&
 651        sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
 652        test_cmp expect output
 653'
 654
 655test_expect_success 'format-patch from a subdirectory (1)' '
 656        filename=$(
 657                rm -rf sub &&
 658                mkdir -p sub/dir &&
 659                cd sub/dir &&
 660                git format-patch -1
 661        ) &&
 662        case "$filename" in
 663        0*)
 664                ;; # ok
 665        *)
 666                echo "Oops? $filename"
 667                false
 668                ;;
 669        esac &&
 670        test -f "$filename"
 671'
 672
 673test_expect_success 'format-patch from a subdirectory (2)' '
 674        filename=$(
 675                rm -rf sub &&
 676                mkdir -p sub/dir &&
 677                cd sub/dir &&
 678                git format-patch -1 -o ..
 679        ) &&
 680        case "$filename" in
 681        ../0*)
 682                ;; # ok
 683        *)
 684                echo "Oops? $filename"
 685                false
 686                ;;
 687        esac &&
 688        basename=$(expr "$filename" : ".*/\(.*\)") &&
 689        test -f "sub/$basename"
 690'
 691
 692test_expect_success 'format-patch from a subdirectory (3)' '
 693        rm -f 0* &&
 694        filename=$(
 695                rm -rf sub &&
 696                mkdir -p sub/dir &&
 697                cd sub/dir &&
 698                git format-patch -1 -o "$TRASH_DIRECTORY"
 699        ) &&
 700        basename=$(expr "$filename" : ".*/\(.*\)") &&
 701        test -f "$basename"
 702'
 703
 704test_expect_success 'format-patch --in-reply-to' '
 705        git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
 706        grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
 707        grep "^References: <baz@foo.bar>" patch8
 708'
 709
 710test_expect_success 'format-patch --signoff' '
 711        git format-patch -1 --signoff --stdout >out &&
 712        grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
 713'
 714
 715test_expect_success 'format-patch --notes --signoff' '
 716        git notes --ref test add -m "test message" HEAD &&
 717        git format-patch -1 --signoff --stdout --notes=test >out &&
 718        # Three dashes must come after S-o-b
 719        ! sed "/^Signed-off-by: /q" out | grep "test message" &&
 720        sed "1,/^Signed-off-by: /d" out | grep "test message" &&
 721        # Notes message must come after three dashes
 722        ! sed "/^---$/q" out | grep "test message" &&
 723        sed "1,/^---$/d" out | grep "test message"
 724'
 725
 726test_expect_success 'format-patch notes output control' '
 727        git notes add -m "notes config message" HEAD &&
 728        test_when_finished git notes remove HEAD &&
 729
 730        git format-patch -1 --stdout >out &&
 731        ! grep "notes config message" out &&
 732        git format-patch -1 --stdout --notes >out &&
 733        grep "notes config message" out &&
 734        git format-patch -1 --stdout --no-notes >out &&
 735        ! grep "notes config message" out &&
 736        git format-patch -1 --stdout --notes --no-notes >out &&
 737        ! grep "notes config message" out &&
 738        git format-patch -1 --stdout --no-notes --notes >out &&
 739        grep "notes config message" out &&
 740
 741        test_config format.notes true &&
 742        git format-patch -1 --stdout >out &&
 743        grep "notes config message" out &&
 744        git format-patch -1 --stdout --notes >out &&
 745        grep "notes config message" out &&
 746        git format-patch -1 --stdout --no-notes >out &&
 747        ! grep "notes config message" out &&
 748        git format-patch -1 --stdout --notes --no-notes >out &&
 749        ! grep "notes config message" out &&
 750        git format-patch -1 --stdout --no-notes --notes >out &&
 751        grep "notes config message" out
 752'
 753
 754test_expect_success 'format-patch with multiple notes refs' '
 755        git notes --ref note1 add -m "this is note 1" HEAD &&
 756        test_when_finished git notes --ref note1 remove HEAD &&
 757        git notes --ref note2 add -m "this is note 2" HEAD &&
 758        test_when_finished git notes --ref note2 remove HEAD &&
 759
 760        git format-patch -1 --stdout >out &&
 761        ! grep "this is note 1" out &&
 762        ! grep "this is note 2" out &&
 763        git format-patch -1 --stdout --notes=note1 >out &&
 764        grep "this is note 1" out &&
 765        ! grep "this is note 2" out &&
 766        git format-patch -1 --stdout --notes=note2 >out &&
 767        ! grep "this is note 1" out &&
 768        grep "this is note 2" out &&
 769        git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
 770        grep "this is note 1" out &&
 771        grep "this is note 2" out &&
 772
 773        test_config format.notes note1 &&
 774        git format-patch -1 --stdout >out &&
 775        grep "this is note 1" out &&
 776        ! grep "this is note 2" out &&
 777        git format-patch -1 --stdout --no-notes >out &&
 778        ! grep "this is note 1" out &&
 779        ! grep "this is note 2" out &&
 780        git format-patch -1 --stdout --notes=note2 >out &&
 781        grep "this is note 1" out &&
 782        grep "this is note 2" out &&
 783        git format-patch -1 --stdout --no-notes --notes=note2 >out &&
 784        ! grep "this is note 1" out &&
 785        grep "this is note 2" out &&
 786
 787        git config --add format.notes note2 &&
 788        git format-patch -1 --stdout >out &&
 789        grep "this is note 1" out &&
 790        grep "this is note 2" out &&
 791        git format-patch -1 --stdout --no-notes >out &&
 792        ! grep "this is note 1" out &&
 793        ! grep "this is note 2" out
 794'
 795
 796echo "fatal: --name-only does not make sense" >expect.name-only
 797echo "fatal: --name-status does not make sense" >expect.name-status
 798echo "fatal: --check does not make sense" >expect.check
 799
 800test_expect_success 'options no longer allowed for format-patch' '
 801        test_must_fail git format-patch --name-only 2>output &&
 802        test_i18ncmp expect.name-only output &&
 803        test_must_fail git format-patch --name-status 2>output &&
 804        test_i18ncmp expect.name-status output &&
 805        test_must_fail git format-patch --check 2>output &&
 806        test_i18ncmp expect.check output
 807'
 808
 809test_expect_success 'format-patch --numstat should produce a patch' '
 810        git format-patch --numstat --stdout master..side >output &&
 811        grep "^diff --git a/" output >diff &&
 812        test_line_count = 5 diff
 813'
 814
 815test_expect_success 'format-patch -- <path>' '
 816        git format-patch master..side -- file 2>error &&
 817        ! grep "Use .--" error
 818'
 819
 820test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
 821        git format-patch --ignore-if-in-upstream HEAD
 822'
 823
 824test_expect_success 'get git version' '
 825        git_version=$(git --version) &&
 826        git_version=${git_version##* }
 827'
 828
 829signature() {
 830        printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
 831}
 832
 833test_expect_success 'format-patch default signature' '
 834        git format-patch --stdout -1 >patch &&
 835        tail -n 3 patch >output &&
 836        signature >expect &&
 837        test_cmp expect output
 838'
 839
 840test_expect_success 'format-patch --signature' '
 841        git format-patch --stdout --signature="my sig" -1 >patch &&
 842        tail -n 3 patch >output &&
 843        signature "my sig" >expect &&
 844        test_cmp expect output
 845'
 846
 847test_expect_success 'format-patch with format.signature config' '
 848        git config format.signature "config sig" &&
 849        git format-patch --stdout -1 >output &&
 850        grep "config sig" output
 851'
 852
 853test_expect_success 'format-patch --signature overrides format.signature' '
 854        git config format.signature "config sig" &&
 855        git format-patch --stdout --signature="overrides" -1 >output &&
 856        ! grep "config sig" output &&
 857        grep "overrides" output
 858'
 859
 860test_expect_success 'format-patch --no-signature ignores format.signature' '
 861        git config format.signature "config sig" &&
 862        git format-patch --stdout --signature="my sig" --no-signature \
 863                -1 >output &&
 864        check_patch output &&
 865        ! grep "config sig" output &&
 866        ! grep "my sig" output &&
 867        ! grep "^-- \$" output
 868'
 869
 870test_expect_success 'format-patch --signature --cover-letter' '
 871        git config --unset-all format.signature &&
 872        git format-patch --stdout --signature="my sig" --cover-letter \
 873                -1 >output &&
 874        grep "my sig" output >sig &&
 875        test_line_count = 2 sig
 876'
 877
 878test_expect_success 'format.signature="" suppresses signatures' '
 879        git config format.signature "" &&
 880        git format-patch --stdout -1 >output &&
 881        check_patch output &&
 882        ! grep "^-- \$" output
 883'
 884
 885test_expect_success 'format-patch --no-signature suppresses signatures' '
 886        git config --unset-all format.signature &&
 887        git format-patch --stdout --no-signature -1 >output &&
 888        check_patch output &&
 889        ! grep "^-- \$" output
 890'
 891
 892test_expect_success 'format-patch --signature="" suppresses signatures' '
 893        git format-patch --stdout --signature="" -1 >output &&
 894        check_patch output &&
 895        ! grep "^-- \$" output
 896'
 897
 898test_expect_success 'prepare mail-signature input' '
 899        cat >mail-signature <<-\EOF
 900
 901        Test User <test.email@kernel.org>
 902        http://git.kernel.org/cgit/git/git.git
 903
 904        git.kernel.org/?p=git/git.git;a=summary
 905
 906        EOF
 907'
 908
 909test_expect_success '--signature-file=file works' '
 910        git format-patch --stdout --signature-file=mail-signature -1 >output &&
 911        check_patch output &&
 912        sed -e "1,/^-- \$/d" output >actual &&
 913        {
 914                cat mail-signature && echo
 915        } >expect &&
 916        test_cmp expect actual
 917'
 918
 919test_expect_success 'format.signaturefile works' '
 920        test_config format.signaturefile mail-signature &&
 921        git format-patch --stdout -1 >output &&
 922        check_patch output &&
 923        sed -e "1,/^-- \$/d" output >actual &&
 924        {
 925                cat mail-signature && echo
 926        } >expect &&
 927        test_cmp expect actual
 928'
 929
 930test_expect_success '--no-signature suppresses format.signaturefile ' '
 931        test_config format.signaturefile mail-signature &&
 932        git format-patch --stdout --no-signature -1 >output &&
 933        check_patch output &&
 934        ! grep "^-- \$" output
 935'
 936
 937test_expect_success '--signature-file overrides format.signaturefile' '
 938        cat >other-mail-signature <<-\EOF &&
 939        Use this other signature instead of mail-signature.
 940        EOF
 941        test_config format.signaturefile mail-signature &&
 942        git format-patch --stdout \
 943                        --signature-file=other-mail-signature -1 >output &&
 944        check_patch output &&
 945        sed -e "1,/^-- \$/d" output >actual &&
 946        {
 947                cat other-mail-signature && echo
 948        } >expect &&
 949        test_cmp expect actual
 950'
 951
 952test_expect_success '--signature overrides format.signaturefile' '
 953        test_config format.signaturefile mail-signature &&
 954        git format-patch --stdout --signature="my sig" -1 >output &&
 955        check_patch output &&
 956        grep "my sig" output
 957'
 958
 959test_expect_success TTY 'format-patch --stdout paginates' '
 960        rm -f pager_used &&
 961        test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
 962        test_path_is_file pager_used
 963'
 964
 965 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
 966        rm -f pager_used &&
 967        test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
 968        test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
 969        test_path_is_missing pager_used &&
 970        test_path_is_missing .git/pager_used
 971'
 972
 973test_expect_success 'format-patch handles multi-line subjects' '
 974        rm -rf patches/ &&
 975        echo content >>file &&
 976        for i in one two three; do echo $i; done >msg &&
 977        git add file &&
 978        git commit -F msg &&
 979        git format-patch -o patches -1 &&
 980        grep ^Subject: patches/0001-one.patch >actual &&
 981        echo "Subject: [PATCH] one two three" >expect &&
 982        test_cmp expect actual
 983'
 984
 985test_expect_success 'format-patch handles multi-line encoded subjects' '
 986        rm -rf patches/ &&
 987        echo content >>file &&
 988        for i in en två tre; do echo $i; done >msg &&
 989        git add file &&
 990        git commit -F msg &&
 991        git format-patch -o patches -1 &&
 992        grep ^Subject: patches/0001-en.patch >actual &&
 993        echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
 994        test_cmp expect actual
 995'
 996
 997M8="foo bar "
 998M64=$M8$M8$M8$M8$M8$M8$M8$M8
 999M512=$M64$M64$M64$M64$M64$M64$M64$M64
1000cat >expect <<'EOF'
1001Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1002 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1003 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1004 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1005 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1006 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1007 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1008EOF
1009test_expect_success 'format-patch wraps extremely long subject (ascii)' '
1010        echo content >>file &&
1011        git add file &&
1012        git commit -m "$M512" &&
1013        git format-patch --stdout -1 >patch &&
1014        sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1015        test_cmp expect subject
1016'
1017
1018M8="föö bar "
1019M64=$M8$M8$M8$M8$M8$M8$M8$M8
1020M512=$M64$M64$M64$M64$M64$M64$M64$M64
1021cat >expect <<'EOF'
1022Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1023 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1024 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1025 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1026 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1027 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1028 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1029 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1030 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1031 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1032 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1033 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1034 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1035 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1036 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1037 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1038 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1039 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1040 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1041 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1042 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1043 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1044 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1045 =?UTF-8?q?bar?=
1046EOF
1047test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
1048        rm -rf patches/ &&
1049        echo content >>file &&
1050        git add file &&
1051        git commit -m "$M512" &&
1052        git format-patch --stdout -1 >patch &&
1053        sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1054        test_cmp expect subject
1055'
1056
1057check_author() {
1058        echo content >>file &&
1059        git add file &&
1060        GIT_AUTHOR_NAME=$1 git commit -m author-check &&
1061        git format-patch --stdout -1 >patch &&
1062        sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1063        test_cmp expect actual
1064}
1065
1066cat >expect <<'EOF'
1067From: "Foo B. Bar" <author@example.com>
1068EOF
1069test_expect_success 'format-patch quotes dot in from-headers' '
1070        check_author "Foo B. Bar"
1071'
1072
1073cat >expect <<'EOF'
1074From: "Foo \"The Baz\" Bar" <author@example.com>
1075EOF
1076test_expect_success 'format-patch quotes double-quote in from-headers' '
1077        check_author "Foo \"The Baz\" Bar"
1078'
1079
1080cat >expect <<'EOF'
1081From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1082EOF
1083test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1084        check_author "Föo Bar"
1085'
1086
1087cat >expect <<'EOF'
1088From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1089EOF
1090test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1091        check_author "Föo B. Bar"
1092'
1093
1094cat >expect <<EOF
1095From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1096 <author@example.com>
1097EOF
1098test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1099        check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1100'
1101
1102cat >expect <<'EOF'
1103From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1104 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1105 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1106EOF
1107test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1108        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"
1109'
1110
1111cat >expect <<'EOF'
1112From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1113 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1114 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1115EOF
1116test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1117        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"
1118'
1119
1120cat >expect <<'EOF'
1121From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1122 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1123 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1124 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1125 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1126EOF
1127test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1128        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"
1129'
1130
1131cat >expect <<'EOF'
1132Subject: header with . in it
1133EOF
1134test_expect_success 'subject lines do not have 822 atom-quoting' '
1135        echo content >>file &&
1136        git add file &&
1137        git commit -m "header with . in it" &&
1138        git format-patch -k -1 --stdout >patch &&
1139        grep ^Subject: patch >actual &&
1140        test_cmp expect actual
1141'
1142
1143cat >expect <<'EOF'
1144Subject: [PREFIX 1/1] header with . in it
1145EOF
1146test_expect_success 'subject prefixes have space prepended' '
1147        git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1148        grep ^Subject: patch >actual &&
1149        test_cmp expect actual
1150'
1151
1152cat >expect <<'EOF'
1153Subject: [1/1] header with . in it
1154EOF
1155test_expect_success 'empty subject prefix does not have extra space' '
1156        git format-patch -n -1 --stdout --subject-prefix= >patch &&
1157        grep ^Subject: patch >actual &&
1158        test_cmp expect actual
1159'
1160
1161test_expect_success '--rfc' '
1162        cat >expect <<-\EOF &&
1163        Subject: [RFC PATCH 1/1] header with . in it
1164        EOF
1165        git format-patch -n -1 --stdout --rfc >patch &&
1166        grep ^Subject: patch >actual &&
1167        test_cmp expect actual
1168'
1169
1170test_expect_success '--from=ident notices bogus ident' '
1171        test_must_fail git format-patch -1 --stdout --from=foo >patch
1172'
1173
1174test_expect_success '--from=ident replaces author' '
1175        git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1176        cat >expect <<-\EOF &&
1177        From: Me <me@example.com>
1178
1179        From: A U Thor <author@example.com>
1180
1181        EOF
1182        sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1183        test_cmp expect patch.head
1184'
1185
1186test_expect_success '--from uses committer ident' '
1187        git format-patch -1 --stdout --from >patch &&
1188        cat >expect <<-\EOF &&
1189        From: C O Mitter <committer@example.com>
1190
1191        From: A U Thor <author@example.com>
1192
1193        EOF
1194        sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1195        test_cmp expect patch.head
1196'
1197
1198test_expect_success '--from omits redundant in-body header' '
1199        git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1200        cat >expect <<-\EOF &&
1201        From: A U Thor <author@example.com>
1202
1203        EOF
1204        sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1205        test_cmp expect patch.head
1206'
1207
1208test_expect_success 'in-body headers trigger content encoding' '
1209        test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1210        test_when_finished "git reset --hard HEAD^" &&
1211        git format-patch -1 --stdout --from >patch &&
1212        cat >expect <<-\EOF &&
1213        From: C O Mitter <committer@example.com>
1214        Content-Type: text/plain; charset=UTF-8
1215
1216        From: éxötìc <author@example.com>
1217
1218        EOF
1219        sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
1220        test_cmp expect patch.head
1221'
1222
1223append_signoff()
1224{
1225        C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1226        git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1227        sed -n -e "1,/^---$/p" append_signoff.patch |
1228                egrep -n "^Subject|Sign|^$"
1229}
1230
1231test_expect_success 'signoff: commit with no body' '
1232        append_signoff </dev/null >actual &&
1233        cat <<-\EOF | sed "s/EOL$//" >expect &&
1234        4:Subject: [PATCH] EOL
1235        8:
1236        9:Signed-off-by: C O Mitter <committer@example.com>
1237        EOF
1238        test_cmp expect actual
1239'
1240
1241test_expect_success 'signoff: commit with only subject' '
1242        echo subject | append_signoff >actual &&
1243        cat >expect <<-\EOF &&
1244        4:Subject: [PATCH] subject
1245        8:
1246        9:Signed-off-by: C O Mitter <committer@example.com>
1247        EOF
1248        test_cmp expect actual
1249'
1250
1251test_expect_success 'signoff: commit with only subject that does not end with NL' '
1252        printf subject | append_signoff >actual &&
1253        cat >expect <<-\EOF &&
1254        4:Subject: [PATCH] subject
1255        8:
1256        9:Signed-off-by: C O Mitter <committer@example.com>
1257        EOF
1258        test_cmp expect actual
1259'
1260
1261test_expect_success 'signoff: no existing signoffs' '
1262        append_signoff <<-\EOF >actual &&
1263        subject
1264
1265        body
1266        EOF
1267        cat >expect <<-\EOF &&
1268        4:Subject: [PATCH] subject
1269        8:
1270        10:
1271        11:Signed-off-by: C O Mitter <committer@example.com>
1272        EOF
1273        test_cmp expect actual
1274'
1275
1276test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1277        printf "subject\n\nbody" | append_signoff >actual &&
1278        cat >expect <<-\EOF &&
1279        4:Subject: [PATCH] subject
1280        8:
1281        10:
1282        11:Signed-off-by: C O Mitter <committer@example.com>
1283        EOF
1284        test_cmp expect actual
1285'
1286
1287test_expect_success 'signoff: some random signoff' '
1288        append_signoff <<-\EOF >actual &&
1289        subject
1290
1291        body
1292
1293        Signed-off-by: my@house
1294        EOF
1295        cat >expect <<-\EOF &&
1296        4:Subject: [PATCH] subject
1297        8:
1298        10:
1299        11:Signed-off-by: my@house
1300        12:Signed-off-by: C O Mitter <committer@example.com>
1301        EOF
1302        test_cmp expect actual
1303'
1304
1305test_expect_success 'signoff: misc conforming footer elements' '
1306        append_signoff <<-\EOF >actual &&
1307        subject
1308
1309        body
1310
1311        Signed-off-by: my@house
1312        (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1313        Tested-by: Some One <someone@example.com>
1314        Bug: 1234
1315        EOF
1316        cat >expect <<-\EOF &&
1317        4:Subject: [PATCH] subject
1318        8:
1319        10:
1320        11:Signed-off-by: my@house
1321        15:Signed-off-by: C O Mitter <committer@example.com>
1322        EOF
1323        test_cmp expect actual
1324'
1325
1326test_expect_success 'signoff: some random signoff-alike' '
1327        append_signoff <<-\EOF >actual &&
1328        subject
1329
1330        body
1331        Fooled-by-me: my@house
1332        EOF
1333        cat >expect <<-\EOF &&
1334        4:Subject: [PATCH] subject
1335        8:
1336        11:
1337        12:Signed-off-by: C O Mitter <committer@example.com>
1338        EOF
1339        test_cmp expect actual
1340'
1341
1342test_expect_success 'signoff: not really a signoff' '
1343        append_signoff <<-\EOF >actual &&
1344        subject
1345
1346        I want to mention about Signed-off-by: here.
1347        EOF
1348        cat >expect <<-\EOF &&
1349        4:Subject: [PATCH] subject
1350        8:
1351        9:I want to mention about Signed-off-by: here.
1352        10:
1353        11:Signed-off-by: C O Mitter <committer@example.com>
1354        EOF
1355        test_cmp expect actual
1356'
1357
1358test_expect_success 'signoff: not really a signoff (2)' '
1359        append_signoff <<-\EOF >actual &&
1360        subject
1361
1362        My unfortunate
1363        Signed-off-by: example happens to be wrapped here.
1364        EOF
1365        cat >expect <<-\EOF &&
1366        4:Subject: [PATCH] subject
1367        8:
1368        10:Signed-off-by: example happens to be wrapped here.
1369        11:Signed-off-by: C O Mitter <committer@example.com>
1370        EOF
1371        test_cmp expect actual
1372'
1373
1374test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1375        append_signoff <<-\EOF >actual &&
1376        subject
1377
1378        Signed-off-by: my@house
1379        Signed-off-by: your@house
1380
1381        A lot of houses.
1382        EOF
1383        cat >expect <<-\EOF &&
1384        4:Subject: [PATCH] subject
1385        8:
1386        9:Signed-off-by: my@house
1387        10:Signed-off-by: your@house
1388        11:
1389        13:
1390        14:Signed-off-by: C O Mitter <committer@example.com>
1391        EOF
1392        test_cmp expect actual
1393'
1394
1395test_expect_success 'signoff: the same signoff at the end' '
1396        append_signoff <<-\EOF >actual &&
1397        subject
1398
1399        body
1400
1401        Signed-off-by: C O Mitter <committer@example.com>
1402        EOF
1403        cat >expect <<-\EOF &&
1404        4:Subject: [PATCH] subject
1405        8:
1406        10:
1407        11:Signed-off-by: C O Mitter <committer@example.com>
1408        EOF
1409        test_cmp expect actual
1410'
1411
1412test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1413        printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1414                append_signoff >actual &&
1415        cat >expect <<-\EOF &&
1416        4:Subject: [PATCH] subject
1417        8:
1418        9:Signed-off-by: C O Mitter <committer@example.com>
1419        EOF
1420        test_cmp expect actual
1421'
1422
1423test_expect_success 'signoff: the same signoff NOT at the end' '
1424        append_signoff <<-\EOF >actual &&
1425        subject
1426
1427        body
1428
1429        Signed-off-by: C O Mitter <committer@example.com>
1430        Signed-off-by: my@house
1431        EOF
1432        cat >expect <<-\EOF &&
1433        4:Subject: [PATCH] subject
1434        8:
1435        10:
1436        11:Signed-off-by: C O Mitter <committer@example.com>
1437        12:Signed-off-by: my@house
1438        EOF
1439        test_cmp expect actual
1440'
1441
1442test_expect_success 'signoff: tolerate garbage in conforming footer' '
1443        append_signoff <<-\EOF >actual &&
1444        subject
1445
1446        body
1447
1448        Tested-by: my@house
1449        Some Trash
1450        Signed-off-by: C O Mitter <committer@example.com>
1451        EOF
1452        cat >expect <<-\EOF &&
1453        4:Subject: [PATCH] subject
1454        8:
1455        10:
1456        13:Signed-off-by: C O Mitter <committer@example.com>
1457        EOF
1458        test_cmp expect actual
1459'
1460
1461test_expect_success 'signoff: respect trailer config' '
1462        append_signoff <<-\EOF >actual &&
1463        subject
1464
1465        Myfooter: x
1466        Some Trash
1467        EOF
1468        cat >expect <<-\EOF &&
1469        4:Subject: [PATCH] subject
1470        8:
1471        11:
1472        12:Signed-off-by: C O Mitter <committer@example.com>
1473        EOF
1474        test_cmp expect actual &&
1475
1476        test_config trailer.Myfooter.ifexists add &&
1477        append_signoff <<-\EOF >actual &&
1478        subject
1479
1480        Myfooter: x
1481        Some Trash
1482        EOF
1483        cat >expect <<-\EOF &&
1484        4:Subject: [PATCH] subject
1485        8:
1486        11:Signed-off-by: C O Mitter <committer@example.com>
1487        EOF
1488        test_cmp expect actual
1489'
1490
1491test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1492        append_signoff <<-\EOF >actual &&
1493        subject
1494
1495        body
1496
1497        Reviewed-id: Noone
1498        Tested-by: my@house
1499        Change-id: Ideadbeef
1500        Signed-off-by: C O Mitter <committer@example.com>
1501        Bug: 1234
1502        EOF
1503        cat >expect <<-\EOF &&
1504        4:Subject: [PATCH] subject
1505        8:
1506        10:
1507        14:Signed-off-by: C O Mitter <committer@example.com>
1508        EOF
1509        test_cmp expect actual
1510'
1511
1512test_expect_success 'format patch ignores color.ui' '
1513        test_unconfig color.ui &&
1514        git format-patch --stdout -1 >expect &&
1515        test_config color.ui always &&
1516        git format-patch --stdout -1 >actual &&
1517        test_cmp expect actual
1518'
1519
1520test_expect_success 'cover letter using branch description (1)' '
1521        git checkout rebuild-1 &&
1522        test_config branch.rebuild-1.description hello &&
1523        git format-patch --stdout --cover-letter master >actual &&
1524        grep hello actual
1525'
1526
1527test_expect_success 'cover letter using branch description (2)' '
1528        git checkout rebuild-1 &&
1529        test_config branch.rebuild-1.description hello &&
1530        git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1531        grep hello actual
1532'
1533
1534test_expect_success 'cover letter using branch description (3)' '
1535        git checkout rebuild-1 &&
1536        test_config branch.rebuild-1.description hello &&
1537        git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1538        grep hello actual
1539'
1540
1541test_expect_success 'cover letter using branch description (4)' '
1542        git checkout rebuild-1 &&
1543        test_config branch.rebuild-1.description hello &&
1544        git format-patch --stdout --cover-letter master.. >actual &&
1545        grep hello actual
1546'
1547
1548test_expect_success 'cover letter using branch description (5)' '
1549        git checkout rebuild-1 &&
1550        test_config branch.rebuild-1.description hello &&
1551        git format-patch --stdout --cover-letter -2 HEAD >actual &&
1552        grep hello actual
1553'
1554
1555test_expect_success 'cover letter using branch description (6)' '
1556        git checkout rebuild-1 &&
1557        test_config branch.rebuild-1.description hello &&
1558        git format-patch --stdout --cover-letter -2 >actual &&
1559        grep hello actual
1560'
1561
1562test_expect_success 'cover letter with nothing' '
1563        git format-patch --stdout --cover-letter >actual &&
1564        test_line_count = 0 actual
1565'
1566
1567test_expect_success 'cover letter auto' '
1568        mkdir -p tmp &&
1569        test_when_finished "rm -rf tmp;
1570                git config --unset format.coverletter" &&
1571
1572        git config format.coverletter auto &&
1573        git format-patch -o tmp -1 >list &&
1574        test_line_count = 1 list &&
1575        git format-patch -o tmp -2 >list &&
1576        test_line_count = 3 list
1577'
1578
1579test_expect_success 'cover letter auto user override' '
1580        mkdir -p tmp &&
1581        test_when_finished "rm -rf tmp;
1582                git config --unset format.coverletter" &&
1583
1584        git config format.coverletter auto &&
1585        git format-patch -o tmp --cover-letter -1 >list &&
1586        test_line_count = 2 list &&
1587        git format-patch -o tmp --cover-letter -2 >list &&
1588        test_line_count = 3 list &&
1589        git format-patch -o tmp --no-cover-letter -1 >list &&
1590        test_line_count = 1 list &&
1591        git format-patch -o tmp --no-cover-letter -2 >list &&
1592        test_line_count = 2 list
1593'
1594
1595test_expect_success 'format-patch --zero-commit' '
1596        git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1597        grep "^From " patch2 | sort | uniq >actual &&
1598        echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1599        test_cmp expect actual
1600'
1601
1602test_expect_success 'From line has expected format' '
1603        git format-patch --stdout v2..v1 >patch2 &&
1604        grep "^From " patch2 >from &&
1605        grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1606        test_cmp from filtered
1607'
1608
1609test_expect_success 'format-patch format.outputDirectory option' '
1610        test_config format.outputDirectory patches &&
1611        rm -fr patches &&
1612        git format-patch master..side &&
1613        git rev-list master..side >list &&
1614        test_line_count = $(ls patches | wc -l) list
1615'
1616
1617test_expect_success 'format-patch -o overrides format.outputDirectory' '
1618        test_config format.outputDirectory patches &&
1619        rm -fr patches patchset &&
1620        git format-patch master..side -o patchset &&
1621        test_path_is_missing patches &&
1622        test_path_is_dir patchset
1623'
1624
1625test_expect_success 'format-patch --base' '
1626        git checkout patchid &&
1627
1628        git format-patch --stdout --base=HEAD~3 -1 >patch &&
1629        tail -n 7 patch >actual1 &&
1630
1631        git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
1632        tail -n 7 patch >actual2 &&
1633
1634        echo >expect &&
1635        git rev-parse HEAD~3 >commit-id-base &&
1636        echo "base-commit: $(cat commit-id-base)" >>expect &&
1637
1638        git show --patch HEAD~2 >patch &&
1639        git patch-id --stable <patch >patch.id.raw &&
1640        awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1641
1642        git show --patch HEAD~1 >patch &&
1643        git patch-id --stable <patch >patch.id.raw &&
1644        awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1645
1646        signature >>expect &&
1647        test_cmp expect actual1 &&
1648        test_cmp expect actual2 &&
1649
1650        echo >fail &&
1651        echo "base-commit: $(cat commit-id-base)" >>fail &&
1652
1653        git show --patch HEAD~2 >patch &&
1654        git patch-id --unstable <patch >patch.id.raw &&
1655        awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1656
1657        git show --patch HEAD~1 >patch &&
1658        git patch-id --unstable <patch >patch.id.raw &&
1659        awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1660
1661        signature >>fail &&
1662        ! test_cmp fail actual1 &&
1663        ! test_cmp fail actual2
1664'
1665
1666test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1667        test_must_fail git format-patch --base=HEAD -2 &&
1668        test_must_fail git format-patch --base=HEAD~1 -2 &&
1669        git format-patch --stdout --base=HEAD~2 -2 >patch &&
1670        grep "^base-commit:" patch >actual &&
1671        git rev-parse HEAD~2 >commit-id-base &&
1672        echo "base-commit: $(cat commit-id-base)" >expect &&
1673        test_cmp expect actual
1674'
1675
1676test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1677        # For history as below:
1678        #
1679        #    ---Q---P---Z---Y---*---X
1680        #        \             /
1681        #         ------------W
1682        #
1683        # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1684        git checkout -b topic1 master &&
1685        git rev-parse HEAD >commit-id-base &&
1686        test_commit P &&
1687        git rev-parse HEAD >commit-id-P &&
1688        test_commit Z &&
1689        git rev-parse HEAD >commit-id-Z &&
1690        test_commit Y &&
1691        git checkout -b topic2 master &&
1692        test_commit W &&
1693        git merge topic1 &&
1694        test_commit X &&
1695        test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1696        test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1697        git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1698        grep "^base-commit:" patch >actual &&
1699        echo "base-commit: $(cat commit-id-base)" >expect &&
1700        test_cmp expect actual
1701'
1702
1703test_expect_success 'format-patch --base=auto' '
1704        git checkout -b upstream master &&
1705        git checkout -b local upstream &&
1706        git branch --set-upstream-to=upstream &&
1707        test_commit N1 &&
1708        test_commit N2 &&
1709        git format-patch --stdout --base=auto -2 >patch &&
1710        grep "^base-commit:" patch >actual &&
1711        git rev-parse upstream >commit-id-base &&
1712        echo "base-commit: $(cat commit-id-base)" >expect &&
1713        test_cmp expect actual
1714'
1715
1716test_expect_success 'format-patch errors out when history involves criss-cross' '
1717        # setup criss-cross history
1718        #
1719        #   B---M1---D
1720        #  / \ /
1721        # A   X
1722        #  \ / \
1723        #   C---M2---E
1724        #
1725        git checkout master &&
1726        test_commit A &&
1727        git checkout -b xb master &&
1728        test_commit B &&
1729        git checkout -b xc master &&
1730        test_commit C &&
1731        git checkout -b xbc xb -- &&
1732        git merge xc &&
1733        git checkout -b xcb xc -- &&
1734        git branch --set-upstream-to=xbc &&
1735        git merge xb &&
1736        git checkout xbc &&
1737        test_commit D &&
1738        git checkout xcb &&
1739        test_commit E &&
1740        test_must_fail  git format-patch --base=auto -1
1741'
1742
1743test_expect_success 'format-patch format.useAutoBaseoption' '
1744        test_when_finished "git config --unset format.useAutoBase" &&
1745        git checkout local &&
1746        git config format.useAutoBase true &&
1747        git format-patch --stdout -1 >patch &&
1748        grep "^base-commit:" patch >actual &&
1749        git rev-parse upstream >commit-id-base &&
1750        echo "base-commit: $(cat commit-id-base)" >expect &&
1751        test_cmp expect actual
1752'
1753
1754test_expect_success 'format-patch --base overrides format.useAutoBase' '
1755        test_when_finished "git config --unset format.useAutoBase" &&
1756        git config format.useAutoBase true &&
1757        git format-patch --stdout --base=HEAD~1 -1 >patch &&
1758        grep "^base-commit:" patch >actual &&
1759        git rev-parse HEAD~1 >commit-id-base &&
1760        echo "base-commit: $(cat commit-id-base)" >expect &&
1761        test_cmp expect actual
1762'
1763
1764test_expect_success 'format-patch --base with --attach' '
1765        git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1766        sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1767                patch >actual &&
1768        test_write_lines 1 2 >expect &&
1769        test_cmp expect actual
1770'
1771test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1772        test_when_finished "rm -fr patches" &&
1773        git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1774        ! egrep "^--+mimemime" patches/0000*.patch &&
1775        egrep "^--+mimemime$" patches/0001*.patch >output &&
1776        test_line_count = 2 output &&
1777        egrep "^--+mimemime--$" patches/0001*.patch >output &&
1778        test_line_count = 1 output
1779'
1780
1781test_expect_success 'format-patch --pretty=mboxrd' '
1782        sp=" " &&
1783        cat >msg <<-INPUT_END &&
1784        mboxrd should escape the body
1785
1786        From could trip up a loose mbox parser
1787        >From extra escape for reversibility
1788        >>From extra escape for reversibility 2
1789        from lower case not escaped
1790        Fromm bad speling not escaped
1791         From with leading space not escaped
1792
1793        F
1794        From
1795        From$sp
1796        From    $sp
1797        From    $sp
1798        INPUT_END
1799
1800        cat >expect <<-INPUT_END &&
1801        >From could trip up a loose mbox parser
1802        >>From extra escape for reversibility
1803        >>>From extra escape for reversibility 2
1804        from lower case not escaped
1805        Fromm bad speling not escaped
1806         From with leading space not escaped
1807
1808        F
1809        From
1810        From
1811        From
1812        From
1813        INPUT_END
1814
1815        C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1816        git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1817        git grep -h --no-index -A11 \
1818                "^>From could trip up a loose mbox parser" patch >actual &&
1819        test_cmp expect actual
1820'
1821
1822test_expect_success 'interdiff: setup' '
1823        git checkout -b boop master &&
1824        test_commit fnorp blorp &&
1825        test_commit fleep blorp
1826'
1827
1828test_expect_success 'interdiff: cover-letter' '
1829        sed "y/q/ /" >expect <<-\EOF &&
1830        +fleep
1831        --q
1832        EOF
1833        git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1834        test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1835        test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1836        sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
1837        test_cmp expect actual
1838'
1839
1840test_expect_success 'interdiff: reroll-count' '
1841        git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1842        test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1843'
1844
1845test_expect_success 'interdiff: solo-patch' '
1846        cat >expect <<-\EOF &&
1847          +fleep
1848
1849        EOF
1850        git format-patch --interdiff=boop~2 -1 boop &&
1851        test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1852        sed "1,/^  @@ /d; /^$/q" 0001-fleep.patch >actual &&
1853        test_cmp expect actual
1854'
1855
1856test_done