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