t4014-format-patch.sh 27.0 KB
Newer Older
1 2 3 4 5
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#

6
test_description='various format-patch tests'
7 8

. ./test-lib.sh
9
. "$TEST_DIRECTORY"/lib-terminal.sh
10 11 12 13

test_expect_success setup '

	for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
14 15
	cat file >elif &&
	git add file elif &&
16
	test_tick &&
17 18 19 20
	git commit -m Initial &&
	git checkout -b side &&

	for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
21
	test_chmod +x elif &&
22
	test_tick &&
23
	git commit -m "Side changes #1" &&
24 25 26

	for i in D E F; do echo "$i"; done >>file &&
	git update-index file &&
27
	test_tick &&
28
	git commit -m "Side changes #2" &&
J
Junio C Hamano 已提交
29
	git tag C2 &&
30 31 32

	for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
	git update-index file &&
33
	test_tick &&
34
	git commit -m "Side changes #3 with \\n backslash-n in it." &&
35 36

	git checkout master &&
J
Junio C Hamano 已提交
37
	git diff-tree -p C2 | git apply --index &&
38
	test_tick &&
J
Junio C Hamano 已提交
39
	git commit -m "Master accepts moral equivalent of #2"
40 41 42 43 44 45 46

'

test_expect_success "format-patch --ignore-if-in-upstream" '

	git format-patch --stdout master..side >patch0 &&
	cnt=`grep "^From " patch0 | wc -l` &&
47
	test $cnt = 3
48 49 50 51 52 53 54 55

'

test_expect_success "format-patch --ignore-if-in-upstream" '

	git format-patch --stdout \
		--ignore-if-in-upstream master..side >patch1 &&
	cnt=`grep "^From " patch1 | wc -l` &&
56
	test $cnt = 2
57 58 59

'

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
test_expect_success "format-patch doesn't consider merge commits" '

	git checkout -b slave master &&
	echo "Another line" >>file &&
	test_tick &&
	git commit -am "Slave change #1" &&
	echo "Yet another line" >>file &&
	test_tick &&
	git commit -am "Slave change #2" &&
	git checkout -b merger master &&
	test_tick &&
	git merge --no-ff slave &&
	cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
	test $cnt = 3
'

76 77 78 79 80
test_expect_success "format-patch result applies" '

	git checkout -b rebuild-0 master &&
	git am -3 patch0 &&
	cnt=`git rev-list master.. | wc -l` &&
81
	test $cnt = 2
82 83 84 85 86 87 88
'

test_expect_success "format-patch --ignore-if-in-upstream result applies" '

	git checkout -b rebuild-1 master &&
	git am -3 patch1 &&
	cnt=`git rev-list master.. | wc -l` &&
89
	test $cnt = 2
90 91
'

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
test_expect_success 'commit did not screw up the log message' '

	git cat-file commit side | grep "^Side .* with .* backslash-n"

'

test_expect_success 'format-patch did not screw up the log message' '

	grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
	grep "^Subject: .*Side changes #3 with .* backslash-n" patch1

'

test_expect_success 'replay did not screw up the log message' '

	git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"

'

111 112
test_expect_success 'extra headers' '

113
	git config format.headers "To: R E Cipient <rcipient@example.com>
114
" &&
115
	git config --add format.headers "Cc: S E Cipient <scipient@example.com>
116 117
" &&
	git format-patch --stdout master..side > patch2 &&
118
	sed -e "/^\$/q" patch2 > hdrs2 &&
119 120
	grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
	grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
121

122 123
'

124
test_expect_success 'extra headers without newlines' '
125

126 127
	git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
	git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
128
	git format-patch --stdout master..side >patch3 &&
129
	sed -e "/^\$/q" patch3 > hdrs3 &&
130 131
	grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
	grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
132

133 134
'

D
Daniel Barkalow 已提交
135
test_expect_success 'extra headers with multiple To:s' '
136

137 138
	git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
	git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
139
	git format-patch --stdout master..side > patch4 &&
140
	sed -e "/^\$/q" patch4 > hdrs4 &&
141 142
	grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
	grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
143 144
'

145
test_expect_success 'additional command line cc (ascii)' '
146

147 148 149 150 151 152 153 154 155
	git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
	git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
	grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
	grep "^ *S E Cipient <scipient@example.com>\$" patch5
'

test_expect_failure 'additional command line cc (rfc822)' '

	git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
156
	git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
157
	grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
J
Junio C Hamano 已提交
158
	grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
159 160
'

161 162 163
test_expect_success 'command line headers' '

	git config --unset-all format.headers &&
164 165
	git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
	grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
166 167 168 169
'

test_expect_success 'configuration headers and command line headers' '

170 171 172 173
	git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
	git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
	grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
	grep "^ *S E Cipient <scipient@example.com>\$" patch7
174 175
'

176
test_expect_success 'command line To: header (ascii)' '
177 178

	git config --unset-all format.headers &&
179 180 181 182 183 184
	git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
	grep "^To: R E Cipient <rcipient@example.com>\$" patch8
'

test_expect_failure 'command line To: header (rfc822)' '

185
	git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
J
Junio C Hamano 已提交
186
	grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
187 188 189 190 191 192
'

test_expect_failure 'command line To: header (rfc2047)' '

	git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
	grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
193 194
'

195 196 197 198 199 200 201 202
test_expect_success 'configuration To: header (ascii)' '

	git config format.to "R E Cipient <rcipient@example.com>" &&
	git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
	grep "^To: R E Cipient <rcipient@example.com>\$" patch9
'

test_expect_failure 'configuration To: header (rfc822)' '
203 204 205

	git config format.to "R. E. Cipient <rcipient@example.com>" &&
	git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
J
Junio C Hamano 已提交
206
	grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
207 208 209 210 211 212 213
'

test_expect_failure 'configuration To: header (rfc2047)' '

	git config format.to "R Ä Cipient <rcipient@example.com>" &&
	git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
	grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
214 215
'

216 217 218 219 220 221 222 223
# check_patch <patch>: Verify that <patch> looks like a half-sane
# patch email to avoid a false positive with !grep
check_patch () {
	grep -e "^From:" "$1" &&
	grep -e "^Date:" "$1" &&
	grep -e "^Subject:" "$1"
}

224 225 226
test_expect_success '--no-to overrides config.to' '

	git config --replace-all format.to \
227
		"R E Cipient <rcipient@example.com>" &&
228 229
	git format-patch --no-to --stdout master..side |
	sed -e "/^\$/q" >patch10 &&
230
	check_patch patch10 &&
231
	! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
232 233 234 235 236 237 238 239 240
'

test_expect_success '--no-to and --to replaces config.to' '

	git config --replace-all format.to \
		"Someone <someone@out.there>" &&
	git format-patch --no-to --to="Someone Else <else@out.there>" \
		--stdout master..side |
	sed -e "/^\$/q" >patch11 &&
241
	check_patch patch11 &&
242 243 244 245 246 247 248
	! grep "^To: Someone <someone@out.there>\$" patch11 &&
	grep "^To: Someone Else <else@out.there>\$" patch11
'

test_expect_success '--no-cc overrides config.cc' '

	git config --replace-all format.cc \
249
		"C E Cipient <rcipient@example.com>" &&
250 251
	git format-patch --no-cc --stdout master..side |
	sed -e "/^\$/q" >patch12 &&
252
	check_patch patch12 &&
253
	! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
254 255
'

256
test_expect_success '--no-add-header overrides config.headers' '
257 258

	git config --replace-all format.headers \
259
		"Header1: B E Cipient <rcipient@example.com>" &&
260
	git format-patch --no-add-header --stdout master..side |
261
	sed -e "/^\$/q" >patch13 &&
262
	check_patch patch13 &&
263
	! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
264 265
'

266 267 268 269 270 271 272 273
test_expect_success 'multiple files' '

	rm -rf patches/ &&
	git checkout side &&
	git format-patch -o patches/ master &&
	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
'

274 275 276 277 278 279
check_threading () {
	expect="$1" &&
	shift &&
	(git format-patch --stdout "$@"; echo $? > status.out) |
	# Prints everything between the Message-ID and In-Reply-To,
	# and replaces all Message-ID-lookalikes by a sequence number
280
	"$PERL_PATH" -ne '
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
		if (/^(message-id|references|in-reply-to)/i) {
			$printing = 1;
		} elsif (/^\S/) {
			$printing = 0;
		}
		if ($printing) {
			$h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
			for $k (keys %h) {s/$k/$h{$k}/};
			print;
		}
		print "---\n" if /^From /i;
	' > actual &&
	test 0 = "$(cat status.out)" &&
	test_cmp "$expect" actual
}

cat >> expect.no-threading <<EOF
---
---
---
EOF

test_expect_success 'no threading' '
304
	git checkout side &&
305
	check_threading expect.no-threading master
306 307
'

308 309 310 311 312 313 314 315 316 317 318 319
cat > expect.thread <<EOF
---
Message-Id: <0>
---
Message-Id: <1>
In-Reply-To: <0>
References: <0>
---
Message-Id: <2>
In-Reply-To: <0>
References: <0>
EOF
320

321 322
test_expect_success 'thread' '
	check_threading expect.thread --thread master
323 324
'

325 326 327 328 329 330 331 332 333 334 335 336 337 338
cat > expect.in-reply-to <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
References: <1>
---
Message-Id: <2>
In-Reply-To: <1>
References: <1>
---
Message-Id: <3>
In-Reply-To: <1>
References: <1>
EOF
339

340 341 342
test_expect_success 'thread in-reply-to' '
	check_threading expect.in-reply-to --in-reply-to="<test.message>" \
		--thread master
343 344
'

345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
cat > expect.cover-letter <<EOF
---
Message-Id: <0>
---
Message-Id: <1>
In-Reply-To: <0>
References: <0>
---
Message-Id: <2>
In-Reply-To: <0>
References: <0>
---
Message-Id: <3>
In-Reply-To: <0>
References: <0>
EOF
361

362 363 364 365 366 367 368 369 370 371 372
test_expect_success 'thread cover-letter' '
	check_threading expect.cover-letter --cover-letter --thread master
'

cat > expect.cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
References: <1>
---
Message-Id: <2>
373
In-Reply-To: <0>
374
References: <1>
375
	<0>
376 377
---
Message-Id: <3>
378
In-Reply-To: <0>
379
References: <1>
380
	<0>
381 382
---
Message-Id: <4>
383
In-Reply-To: <0>
384
References: <1>
385
	<0>
386 387 388 389 390
EOF

test_expect_success 'thread cover-letter in-reply-to' '
	check_threading expect.cl-irt --cover-letter \
		--in-reply-to="<test.message>" --thread master
391 392
'

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
test_expect_success 'thread explicit shallow' '
	check_threading expect.cl-irt --cover-letter \
		--in-reply-to="<test.message>" --thread=shallow master
'

cat > expect.deep <<EOF
---
Message-Id: <0>
---
Message-Id: <1>
In-Reply-To: <0>
References: <0>
---
Message-Id: <2>
In-Reply-To: <1>
References: <0>
	<1>
EOF

test_expect_success 'thread deep' '
	check_threading expect.deep --thread=deep master
'

cat > expect.deep-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
References: <1>
---
Message-Id: <2>
In-Reply-To: <0>
References: <1>
	<0>
---
Message-Id: <3>
In-Reply-To: <2>
References: <1>
	<0>
	<2>
EOF

test_expect_success 'thread deep in-reply-to' '
	check_threading expect.deep-irt  --thread=deep \
		--in-reply-to="<test.message>" master
'

cat > expect.deep-cl <<EOF
---
Message-Id: <0>
---
Message-Id: <1>
In-Reply-To: <0>
References: <0>
---
Message-Id: <2>
In-Reply-To: <1>
References: <0>
	<1>
---
Message-Id: <3>
In-Reply-To: <2>
References: <0>
	<1>
	<2>
EOF

test_expect_success 'thread deep cover-letter' '
	check_threading expect.deep-cl --cover-letter --thread=deep master
'

cat > expect.deep-cl-irt <<EOF
---
Message-Id: <0>
In-Reply-To: <1>
References: <1>
---
Message-Id: <2>
In-Reply-To: <0>
References: <1>
	<0>
---
Message-Id: <3>
In-Reply-To: <2>
References: <1>
	<0>
	<2>
---
Message-Id: <4>
In-Reply-To: <3>
References: <1>
	<0>
	<2>
	<3>
EOF

test_expect_success 'thread deep cover-letter in-reply-to' '
	check_threading expect.deep-cl-irt --cover-letter \
		--in-reply-to="<test.message>" --thread=deep master
'

test_expect_success 'thread via config' '
494
	test_config format.thread true &&
495 496 497 498
	check_threading expect.thread master
'

test_expect_success 'thread deep via config' '
499
	test_config format.thread deep &&
500 501 502 503
	check_threading expect.deep master
'

test_expect_success 'thread config + override' '
504
	test_config format.thread deep &&
505 506 507 508
	check_threading expect.thread --thread master
'

test_expect_success 'thread config + --no-thread' '
509
	test_config format.thread deep &&
510 511 512
	check_threading expect.no-threading --no-thread master
'

513 514 515 516 517 518 519 520 521 522 523
test_expect_success 'excessive subject' '

	rm -rf patches/ &&
	git checkout side &&
	for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
	git update-index file &&
	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." &&
	git format-patch -o patches/ master..side &&
	ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
'

524 525 526 527 528
test_expect_success 'cover-letter inherits diff options' '

	git mv file foo &&
	git commit -m foo &&
	git format-patch --cover-letter -1 &&
529
	check_patch 0000-cover-letter.patch &&
530
	! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
531
	git format-patch --cover-letter -1 -M &&
532
	grep "file => foo .* 0 *\$" 0000-cover-letter.patch
533 534

'
535 536 537 538 539 540 541 542 543 544 545 546 547 548

cat > expect << EOF
  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.
  foo

EOF

test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '

	git format-patch --cover-letter -2 &&
549
	sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
550
	test_cmp expect output
551 552 553

'

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
cat > expect << EOF
index 40f36c6..2dc5c23 100644
--- a/file
+++ b/file
@@ -13,4 +13,20 @@ C
 10
 D
 E
 F
+5
EOF

test_expect_success 'format-patch respects -U' '

	git format-patch -U4 -2 &&
569 570 571
	sed -e "1,/^diff/d" -e "/^+5/q" \
		<0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
		>output &&
572 573 574 575
	test_cmp expect output

'

576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
cat > expect << EOF

diff --git a/file b/file
index 40f36c6..2dc5c23 100644
--- a/file
+++ b/file
@@ -14,3 +14,19 @@ C
 D
 E
 F
+5
EOF

test_expect_success 'format-patch -p suppresses stat' '

	git format-patch -p -2 &&
592
	sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
593 594 595 596
	test_cmp expect output

'

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
test_expect_success 'format-patch from a subdirectory (1)' '
	filename=$(
		rm -rf sub &&
		mkdir -p sub/dir &&
		cd sub/dir &&
		git format-patch -1
	) &&
	case "$filename" in
	0*)
		;; # ok
	*)
		echo "Oops? $filename"
		false
		;;
	esac &&
	test -f "$filename"
'

test_expect_success 'format-patch from a subdirectory (2)' '
	filename=$(
		rm -rf sub &&
		mkdir -p sub/dir &&
		cd sub/dir &&
		git format-patch -1 -o ..
	) &&
	case "$filename" in
	../0*)
		;; # ok
	*)
		echo "Oops? $filename"
		false
		;;
	esac &&
	basename=$(expr "$filename" : ".*/\(.*\)") &&
	test -f "sub/$basename"
'

test_expect_success 'format-patch from a subdirectory (3)' '
	rm -f 0* &&
	filename=$(
		rm -rf sub &&
		mkdir -p sub/dir &&
		cd sub/dir &&
640
		git format-patch -1 -o "$TRASH_DIRECTORY"
641 642 643 644 645
	) &&
	basename=$(expr "$filename" : ".*/\(.*\)") &&
	test -f "$basename"
'

646 647 648 649 650 651 652
test_expect_success 'format-patch --in-reply-to' '
	git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
	grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
	grep "^References: <baz@foo.bar>" patch8
'

test_expect_success 'format-patch --signoff' '
653 654 655 656 657 658 659
	git format-patch -1 --signoff --stdout >out &&
	grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
'

test_expect_success 'format-patch --notes --signoff' '
	git notes --ref test add -m "test message" HEAD &&
	git format-patch -1 --signoff --stdout --notes=test >out &&
660
	# Three dashes must come after S-o-b
661
	! sed "/^Signed-off-by: /q" out | grep "test message" &&
662 663 664 665
	sed "1,/^Signed-off-by: /d" out | grep "test message" &&
	# Notes message must come after three dashes
	! sed "/^---$/q" out | grep "test message" &&
	sed "1,/^---$/d" out | grep "test message"
666 667
'

668 669 670 671
echo "fatal: --name-only does not make sense" > expect.name-only
echo "fatal: --name-status does not make sense" > expect.name-status
echo "fatal: --check does not make sense" > expect.check

672
test_expect_success 'options no longer allowed for format-patch' '
673
	test_must_fail git format-patch --name-only 2> output &&
674
	test_i18ncmp expect.name-only output &&
675
	test_must_fail git format-patch --name-status 2> output &&
676
	test_i18ncmp expect.name-status output &&
677
	test_must_fail git format-patch --check 2> output &&
678
	test_i18ncmp expect.check output'
679 680

test_expect_success 'format-patch --numstat should produce a patch' '
681 682
	git format-patch --numstat --stdout master..side > output &&
	test 6 = $(grep "^diff --git a/" output | wc -l)'
683

684 685 686 687 688
test_expect_success 'format-patch -- <path>' '
	git format-patch master..side -- file 2>error &&
	! grep "Use .--" error
'

689 690 691 692
test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
	git format-patch --ignore-if-in-upstream HEAD
'

693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
test_expect_success 'format-patch --signature' '
	git format-patch --stdout --signature="my sig" -1 >output &&
	grep "my sig" output
'

test_expect_success 'format-patch with format.signature config' '
	git config format.signature "config sig" &&
	git format-patch --stdout -1 >output &&
	grep "config sig" output
'

test_expect_success 'format-patch --signature overrides format.signature' '
	git config format.signature "config sig" &&
	git format-patch --stdout --signature="overrides" -1 >output &&
	! grep "config sig" output &&
	grep "overrides" output
'

test_expect_success 'format-patch --no-signature ignores format.signature' '
	git config format.signature "config sig" &&
	git format-patch --stdout --signature="my sig" --no-signature \
		-1 >output &&
715
	check_patch output &&
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
	! grep "config sig" output &&
	! grep "my sig" output &&
	! grep "^-- \$" output
'

test_expect_success 'format-patch --signature --cover-letter' '
	git config --unset-all format.signature &&
	git format-patch --stdout --signature="my sig" --cover-letter \
		-1 >output &&
	grep "my sig" output &&
	test 2 = $(grep "my sig" output | wc -l)
'

test_expect_success 'format.signature="" supresses signatures' '
	git config format.signature "" &&
	git format-patch --stdout -1 >output &&
732
	check_patch output &&
733 734 735 736 737 738
	! grep "^-- \$" output
'

test_expect_success 'format-patch --no-signature supresses signatures' '
	git config --unset-all format.signature &&
	git format-patch --stdout --no-signature -1 >output &&
739
	check_patch output &&
740 741 742
	! grep "^-- \$" output
'

743 744
test_expect_success 'format-patch --signature="" supresses signatures' '
	git format-patch --stdout --signature="" -1 >output &&
745
	check_patch output &&
746 747 748
	! grep "^-- \$" output
'

749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
test_expect_success TTY 'format-patch --stdout paginates' '
	rm -f pager_used &&
	(
		GIT_PAGER="wc >pager_used" &&
		export GIT_PAGER &&
		test_terminal git format-patch --stdout --all
	) &&
	test_path_is_file pager_used
'

 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
	rm -f pager_used &&
	(
		GIT_PAGER="wc >pager_used" &&
		export GIT_PAGER &&
		test_terminal git --no-pager format-patch --stdout --all &&
		test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
	) &&
	test_path_is_missing pager_used &&
	test_path_is_missing .git/pager_used
'

J
Jeff King 已提交
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
test_expect_success 'format-patch handles multi-line subjects' '
	rm -rf patches/ &&
	echo content >>file &&
	for i in one two three; do echo $i; done >msg &&
	git add file &&
	git commit -F msg &&
	git format-patch -o patches -1 &&
	grep ^Subject: patches/0001-one.patch >actual &&
	echo "Subject: [PATCH] one two three" >expect &&
	test_cmp expect actual
'

test_expect_success 'format-patch handles multi-line encoded subjects' '
	rm -rf patches/ &&
	echo content >>file &&
	for i in en två tre; do echo $i; done >msg &&
	git add file &&
	git commit -F msg &&
	git format-patch -o patches -1 &&
	grep ^Subject: patches/0001-en.patch >actual &&
	echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
	test_cmp expect actual
'

M8="foo bar "
M64=$M8$M8$M8$M8$M8$M8$M8$M8
M512=$M64$M64$M64$M64$M64$M64$M64$M64
cat >expect <<'EOF'
Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
800 801 802 803 804 805
 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 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 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
J
Jeff King 已提交
806
EOF
807
test_expect_success 'format-patch wraps extremely long subject (ascii)' '
J
Jeff King 已提交
808 809 810 811 812 813 814 815 816 817 818 819
	echo content >>file &&
	git add file &&
	git commit -m "$M512" &&
	git format-patch --stdout -1 >patch &&
	sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
	test_cmp expect subject
'

M8="föö bar "
M64=$M8$M8$M8$M8$M8$M8$M8$M8
M512=$M64$M64$M64$M64$M64$M64$M64$M64
cat >expect <<'EOF'
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
J
Jeff King 已提交
843
EOF
844
test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
J
Jeff King 已提交
845 846 847 848 849 850 851 852 853
	rm -rf patches/ &&
	echo content >>file &&
	git add file &&
	git commit -m "$M512" &&
	git format-patch --stdout -1 >patch &&
	sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
	test_cmp expect subject
'

854 855 856 857 858
check_author() {
	echo content >>file &&
	git add file &&
	GIT_AUTHOR_NAME=$1 git commit -m author-check &&
	git format-patch --stdout -1 >patch &&
859
	sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
860 861 862 863 864 865
	test_cmp expect actual
}

cat >expect <<'EOF'
From: "Foo B. Bar" <author@example.com>
EOF
866
test_expect_success 'format-patch quotes dot in from-headers' '
867 868 869 870 871 872
	check_author "Foo B. Bar"
'

cat >expect <<'EOF'
From: "Foo \"The Baz\" Bar" <author@example.com>
EOF
873
test_expect_success 'format-patch quotes double-quote in from-headers' '
874 875 876 877
	check_author "Foo \"The Baz\" Bar"
'

cat >expect <<'EOF'
878
From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
879
EOF
880 881 882 883 884 885 886
test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
	check_author "Föo Bar"
'

cat >expect <<'EOF'
From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
EOF
887
test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
888 889 890
	check_author "Föo B. Bar"
'

891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
cat >expect <<EOF
From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
 <author@example.com>
EOF
test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
	check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
'

cat >expect <<'EOF'
From: 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 <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
	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"
'

cat >expect <<'EOF'
From: "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" <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
	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"
'

917
cat >expect <<'EOF'
918 919 920 921 922 923 924 925 926 927 928
From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
	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"
'

cat >expect <<'EOF'
929 930 931 932 933 934 935 936 937 938 939
Subject: header with . in it
EOF
test_expect_success 'subject lines do not have 822 atom-quoting' '
	echo content >>file &&
	git add file &&
	git commit -m "header with . in it" &&
	git format-patch -k -1 --stdout >patch &&
	grep ^Subject: patch >actual &&
	test_cmp expect actual
'

940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
cat >expect <<'EOF'
Subject: [PREFIX 1/1] header with . in it
EOF
test_expect_success 'subject prefixes have space prepended' '
	git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
	grep ^Subject: patch >actual &&
	test_cmp expect actual
'

cat >expect <<'EOF'
Subject: [1/1] header with . in it
EOF
test_expect_success 'empty subject prefix does not have extra space' '
	git format-patch -n -1 --stdout --subject-prefix= >patch &&
	grep ^Subject: patch >actual &&
	test_cmp expect actual
'

P
Pang Yan Han 已提交
958 959 960 961 962 963 964 965
test_expect_success 'format patch ignores color.ui' '
	test_unconfig color.ui &&
	git format-patch --stdout -1 >expect &&
	test_config color.ui always &&
	git format-patch --stdout -1 >actual &&
	test_cmp expect actual
'

966
test_done