345e6deab6155ae89ff6a24497c994f199581466
   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: <1>
 241References: <1>
 242---
 243Message-Id: <3>
 244In-Reply-To: <1>
 245References: <1>
 246---
 247Message-Id: <4>
 248In-Reply-To: <1>
 249References: <1>
 250EOF
 251
 252test_expect_success 'thread cover-letter in-reply-to' '
 253        check_threading expect.cl-irt --cover-letter \
 254                --in-reply-to="<test.message>" --thread master
 255'
 256
 257test_expect_success 'excessive subject' '
 258
 259        rm -rf patches/ &&
 260        git checkout side &&
 261        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
 262        git update-index file &&
 263        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." &&
 264        git format-patch -o patches/ master..side &&
 265        ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
 266'
 267
 268test_expect_success 'cover-letter inherits diff options' '
 269
 270        git mv file foo &&
 271        git commit -m foo &&
 272        git format-patch --cover-letter -1 &&
 273        ! grep "file => foo .* 0 *$" 0000-cover-letter.patch &&
 274        git format-patch --cover-letter -1 -M &&
 275        grep "file => foo .* 0 *$" 0000-cover-letter.patch
 276
 277'
 278
 279cat > expect << EOF
 280  This is an excessively long subject line for a message due to the
 281    habit some projects have of not having a short, one-line subject at
 282    the start of the commit message, but rather sticking a whole
 283    paragraph right at the start as the only thing in the commit
 284    message. It had better not become the filename for the patch.
 285  foo
 286
 287EOF
 288
 289test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 290
 291        git format-patch --cover-letter -2 &&
 292        sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output &&
 293        test_cmp expect output
 294
 295'
 296
 297cat > expect << EOF
 298---
 299 file |   16 ++++++++++++++++
 300 1 files changed, 16 insertions(+), 0 deletions(-)
 301
 302diff --git a/file b/file
 303index 40f36c6..2dc5c23 100644
 304--- a/file
 305+++ b/file
 306@@ -13,4 +13,20 @@ C
 307 10
 308 D
 309 E
 310 F
 311+5
 312EOF
 313
 314test_expect_success 'format-patch respects -U' '
 315
 316        git format-patch -U4 -2 &&
 317        sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
 318        test_cmp expect output
 319
 320'
 321
 322test_expect_success 'format-patch from a subdirectory (1)' '
 323        filename=$(
 324                rm -rf sub &&
 325                mkdir -p sub/dir &&
 326                cd sub/dir &&
 327                git format-patch -1
 328        ) &&
 329        case "$filename" in
 330        0*)
 331                ;; # ok
 332        *)
 333                echo "Oops? $filename"
 334                false
 335                ;;
 336        esac &&
 337        test -f "$filename"
 338'
 339
 340test_expect_success 'format-patch from a subdirectory (2)' '
 341        filename=$(
 342                rm -rf sub &&
 343                mkdir -p sub/dir &&
 344                cd sub/dir &&
 345                git format-patch -1 -o ..
 346        ) &&
 347        case "$filename" in
 348        ../0*)
 349                ;; # ok
 350        *)
 351                echo "Oops? $filename"
 352                false
 353                ;;
 354        esac &&
 355        basename=$(expr "$filename" : ".*/\(.*\)") &&
 356        test -f "sub/$basename"
 357'
 358
 359test_expect_success 'format-patch from a subdirectory (3)' '
 360        here="$TEST_DIRECTORY/$test" &&
 361        rm -f 0* &&
 362        filename=$(
 363                rm -rf sub &&
 364                mkdir -p sub/dir &&
 365                cd sub/dir &&
 366                git format-patch -1 -o "$here"
 367        ) &&
 368        basename=$(expr "$filename" : ".*/\(.*\)") &&
 369        test -f "$basename"
 370'
 371
 372test_done