t / t4014-format-patch.shon commit Merge branch 'maint' (b0085a7)
   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
  10test_expect_success setup '
  11
  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        git commit -m Initial &&
  16        git checkout -b side &&
  17
  18        for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
  19        test_chmod +x elif &&
  20        git commit -m "Side changes #1" &&
  21
  22        for i in D E F; do echo "$i"; done >>file &&
  23        git update-index file &&
  24        git commit -m "Side changes #2" &&
  25        git tag C2 &&
  26
  27        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
  28        git update-index file &&
  29        git commit -m "Side changes #3 with \\n backslash-n in it." &&
  30
  31        git checkout master &&
  32        git diff-tree -p C2 | git apply --index &&
  33        git commit -m "Master accepts moral equivalent of #2"
  34
  35'
  36
  37test_expect_success "format-patch --ignore-if-in-upstream" '
  38
  39        git format-patch --stdout master..side >patch0 &&
  40        cnt=`grep "^From " patch0 | wc -l` &&
  41        test $cnt = 3
  42
  43'
  44
  45test_expect_success "format-patch --ignore-if-in-upstream" '
  46
  47        git format-patch --stdout \
  48                --ignore-if-in-upstream master..side >patch1 &&
  49        cnt=`grep "^From " patch1 | wc -l` &&
  50        test $cnt = 2
  51
  52'
  53
  54test_expect_success "format-patch result applies" '
  55
  56        git checkout -b rebuild-0 master &&
  57        git am -3 patch0 &&
  58        cnt=`git rev-list master.. | wc -l` &&
  59        test $cnt = 2
  60'
  61
  62test_expect_success "format-patch --ignore-if-in-upstream result applies" '
  63
  64        git checkout -b rebuild-1 master &&
  65        git am -3 patch1 &&
  66        cnt=`git rev-list master.. | wc -l` &&
  67        test $cnt = 2
  68'
  69
  70test_expect_success 'commit did not screw up the log message' '
  71
  72        git cat-file commit side | grep "^Side .* with .* backslash-n"
  73
  74'
  75
  76test_expect_success 'format-patch did not screw up the log message' '
  77
  78        grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
  79        grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
  80
  81'
  82
  83test_expect_success 'replay did not screw up the log message' '
  84
  85        git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
  86
  87'
  88
  89test_expect_success 'extra headers' '
  90
  91        git config format.headers "To: R. E. Cipient <rcipient@example.com>
  92" &&
  93        git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
  94" &&
  95        git format-patch --stdout master..side > patch2 &&
  96        sed -e "/^$/q" patch2 > hdrs2 &&
  97        grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs2 &&
  98        grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs2
  99
 100'
 101
 102test_expect_success 'extra headers without newlines' '
 103
 104        git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
 105        git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
 106        git format-patch --stdout master..side >patch3 &&
 107        sed -e "/^$/q" patch3 > hdrs3 &&
 108        grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs3 &&
 109        grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs3
 110
 111'
 112
 113test_expect_success 'extra headers with multiple To:s' '
 114
 115        git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
 116        git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
 117        git format-patch --stdout master..side > patch4 &&
 118        sed -e "/^$/q" patch4 > hdrs4 &&
 119        grep "^To: R. E. Cipient <rcipient@example.com>,$" hdrs4 &&
 120        grep "^ *S. E. Cipient <scipient@example.com>$" hdrs4
 121'
 122
 123test_expect_success 'additional command line cc' '
 124
 125        git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
 126        git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch5 &&
 127        grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch5 &&
 128        grep "^ *S. E. Cipient <scipient@example.com>$" patch5
 129'
 130
 131test_expect_success 'multiple files' '
 132
 133        rm -rf patches/ &&
 134        git checkout side &&
 135        git format-patch -o patches/ master &&
 136        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
 137'
 138
 139check_threading () {
 140        expect="$1" &&
 141        shift &&
 142        (git format-patch --stdout "$@"; echo $? > status.out) |
 143        # Prints everything between the Message-ID and In-Reply-To,
 144        # and replaces all Message-ID-lookalikes by a sequence number
 145        perl -ne '
 146                if (/^(message-id|references|in-reply-to)/i) {
 147                        $printing = 1;
 148                } elsif (/^\S/) {
 149                        $printing = 0;
 150                }
 151                if ($printing) {
 152                        $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
 153                        for $k (keys %h) {s/$k/$h{$k}/};
 154                        print;
 155                }
 156                print "---\n" if /^From /i;
 157        ' > actual &&
 158        test 0 = "$(cat status.out)" &&
 159        test_cmp "$expect" actual
 160}
 161
 162cat >> expect.no-threading <<EOF
 163---
 164---
 165---
 166EOF
 167
 168test_expect_success 'no threading' '
 169        git checkout side &&
 170        check_threading expect.no-threading master
 171'
 172
 173cat > expect.thread <<EOF
 174---
 175Message-Id: <0>
 176---
 177Message-Id: <1>
 178In-Reply-To: <0>
 179References: <0>
 180---
 181Message-Id: <2>
 182In-Reply-To: <0>
 183References: <0>
 184EOF
 185
 186test_expect_success 'thread' '
 187        check_threading expect.thread --thread master
 188'
 189
 190cat > expect.in-reply-to <<EOF
 191---
 192Message-Id: <0>
 193In-Reply-To: <1>
 194References: <1>
 195---
 196Message-Id: <2>
 197In-Reply-To: <1>
 198References: <1>
 199---
 200Message-Id: <3>
 201In-Reply-To: <1>
 202References: <1>
 203EOF
 204
 205test_expect_success 'thread in-reply-to' '
 206        check_threading expect.in-reply-to --in-reply-to="<test.message>" \
 207                --thread master
 208'
 209
 210cat > expect.cover-letter <<EOF
 211---
 212Message-Id: <0>
 213---
 214Message-Id: <1>
 215In-Reply-To: <0>
 216References: <0>
 217---
 218Message-Id: <2>
 219In-Reply-To: <0>
 220References: <0>
 221---
 222Message-Id: <3>
 223In-Reply-To: <0>
 224References: <0>
 225EOF
 226
 227test_expect_success 'thread cover-letter' '
 228        check_threading expect.cover-letter --cover-letter --thread master
 229'
 230
 231cat > expect.cl-irt <<EOF
 232---
 233Message-Id: <0>
 234In-Reply-To: <1>
 235References: <1>
 236---
 237Message-Id: <2>
 238In-Reply-To: <0>
 239References: <1>
 240        <0>
 241---
 242Message-Id: <3>
 243In-Reply-To: <0>
 244References: <1>
 245        <0>
 246---
 247Message-Id: <4>
 248In-Reply-To: <0>
 249References: <1>
 250        <0>
 251EOF
 252
 253test_expect_success 'thread cover-letter in-reply-to' '
 254        check_threading expect.cl-irt --cover-letter \
 255                --in-reply-to="<test.message>" --thread master
 256'
 257
 258test_expect_success 'thread explicit shallow' '
 259        check_threading expect.cl-irt --cover-letter \
 260                --in-reply-to="<test.message>" --thread=shallow master
 261'
 262
 263cat > expect.deep <<EOF
 264---
 265Message-Id: <0>
 266---
 267Message-Id: <1>
 268In-Reply-To: <0>
 269References: <0>
 270---
 271Message-Id: <2>
 272In-Reply-To: <1>
 273References: <0>
 274        <1>
 275EOF
 276
 277test_expect_success 'thread deep' '
 278        check_threading expect.deep --thread=deep master
 279'
 280
 281cat > expect.deep-irt <<EOF
 282---
 283Message-Id: <0>
 284In-Reply-To: <1>
 285References: <1>
 286---
 287Message-Id: <2>
 288In-Reply-To: <0>
 289References: <1>
 290        <0>
 291---
 292Message-Id: <3>
 293In-Reply-To: <2>
 294References: <1>
 295        <0>
 296        <2>
 297EOF
 298
 299test_expect_success 'thread deep in-reply-to' '
 300        check_threading expect.deep-irt  --thread=deep \
 301                --in-reply-to="<test.message>" master
 302'
 303
 304cat > expect.deep-cl <<EOF
 305---
 306Message-Id: <0>
 307---
 308Message-Id: <1>
 309In-Reply-To: <0>
 310References: <0>
 311---
 312Message-Id: <2>
 313In-Reply-To: <1>
 314References: <0>
 315        <1>
 316---
 317Message-Id: <3>
 318In-Reply-To: <2>
 319References: <0>
 320        <1>
 321        <2>
 322EOF
 323
 324test_expect_success 'thread deep cover-letter' '
 325        check_threading expect.deep-cl --cover-letter --thread=deep master
 326'
 327
 328cat > expect.deep-cl-irt <<EOF
 329---
 330Message-Id: <0>
 331In-Reply-To: <1>
 332References: <1>
 333---
 334Message-Id: <2>
 335In-Reply-To: <0>
 336References: <1>
 337        <0>
 338---
 339Message-Id: <3>
 340In-Reply-To: <2>
 341References: <1>
 342        <0>
 343        <2>
 344---
 345Message-Id: <4>
 346In-Reply-To: <3>
 347References: <1>
 348        <0>
 349        <2>
 350        <3>
 351EOF
 352
 353test_expect_success 'thread deep cover-letter in-reply-to' '
 354        check_threading expect.deep-cl-irt --cover-letter \
 355                --in-reply-to="<test.message>" --thread=deep master
 356'
 357
 358test_expect_success 'thread via config' '
 359        git config format.thread true &&
 360        check_threading expect.thread master
 361'
 362
 363test_expect_success 'thread deep via config' '
 364        git config format.thread deep &&
 365        check_threading expect.deep master
 366'
 367
 368test_expect_success 'thread config + override' '
 369        git config format.thread deep &&
 370        check_threading expect.thread --thread master
 371'
 372
 373test_expect_success 'thread config + --no-thread' '
 374        git config format.thread deep &&
 375        check_threading expect.no-threading --no-thread master
 376'
 377
 378test_expect_success 'excessive subject' '
 379
 380        rm -rf patches/ &&
 381        git checkout side &&
 382        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 383        git update-index file &&
 384        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." &&
 385        git format-patch -o patches/ master..side &&
 386        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 387'
 388
 389test_expect_success 'cover-letter inherits diff options' '
 390
 391        git mv file foo &&
 392        git commit -m foo &&
 393        git format-patch --cover-letter -1 &&
 394        ! grep "file => foo .* 0 *$" 0000-cover-letter.patch &&
 395        git format-patch --cover-letter -1 -M &&
 396        grep "file => foo .* 0 *$" 0000-cover-letter.patch
 397
 398'
 399
 400cat > expect << EOF
 401  This is an excessively long subject line for a message due to the
 402    habit some projects have of not having a short, one-line subject at
 403    the start of the commit message, but rather sticking a whole
 404    paragraph right at the start as the only thing in the commit
 405    message. It had better not become the filename for the patch.
 406  foo
 407
 408EOF
 409
 410test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 411
 412        git format-patch --cover-letter -2 &&
 413        sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output &&
 414        test_cmp expect output
 415
 416'
 417
 418cat > expect << EOF
 419---
 420 file |   16 ++++++++++++++++
 421 1 files changed, 16 insertions(+), 0 deletions(-)
 422
 423diff --git a/file b/file
 424index 40f36c6..2dc5c23 100644
 425--- a/file
 426+++ b/file
 427@@ -13,4 +13,20 @@ C
 428 10
 429 D
 430 E
 431 F
 432+5
 433EOF
 434
 435test_expect_success 'format-patch respects -U' '
 436
 437        git format-patch -U4 -2 &&
 438        sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 439        test_cmp expect output
 440
 441'
 442
 443test_expect_success 'format-patch from a subdirectory (1)' '
 444        filename=$(
 445                rm -rf sub &&
 446                mkdir -p sub/dir &&
 447                cd sub/dir &&
 448                git format-patch -1
 449        ) &&
 450        case "$filename" in
 451        0*)
 452                ;; # ok
 453        *)
 454                echo "Oops? $filename"
 455                false
 456                ;;
 457        esac &&
 458        test -f "$filename"
 459'
 460
 461test_expect_success 'format-patch from a subdirectory (2)' '
 462        filename=$(
 463                rm -rf sub &&
 464                mkdir -p sub/dir &&
 465                cd sub/dir &&
 466                git format-patch -1 -o ..
 467        ) &&
 468        case "$filename" in
 469        ../0*)
 470                ;; # ok
 471        *)
 472                echo "Oops? $filename"
 473                false
 474                ;;
 475        esac &&
 476        basename=$(expr "$filename" : ".*/\(.*\)") &&
 477        test -f "sub/$basename"
 478'
 479
 480test_expect_success 'format-patch from a subdirectory (3)' '
 481        here="$TEST_DIRECTORY/$test" &&
 482        rm -f 0* &&
 483        filename=$(
 484                rm -rf sub &&
 485                mkdir -p sub/dir &&
 486                cd sub/dir &&
 487                git format-patch -1 -o "$here"
 488        ) &&
 489        basename=$(expr "$filename" : ".*/\(.*\)") &&
 490        test -f "$basename"
 491'
 492
 493test_done