]>
Commit | Line | Data |
---|---|---|
ece3c67f JH |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2006 Junio C Hamano | |
4 | # | |
5 | ||
9800a754 | 6 | test_description='various format-patch tests' |
ece3c67f JH |
7 | |
8 | . ./test-lib.sh | |
9 | ||
10 | test_expect_success setup ' | |
11 | ||
12 | for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file && | |
cd894ee9 JH |
13 | cat file >elif && |
14 | git add file elif && | |
ece3c67f JH |
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 && | |
1f553918 | 19 | test_chmod +x elif && |
816366e2 | 20 | git commit -m "Side changes #1" && |
ece3c67f JH |
21 | |
22 | for i in D E F; do echo "$i"; done >>file && | |
23 | git update-index file && | |
816366e2 | 24 | git commit -m "Side changes #2" && |
982b64e4 | 25 | git tag C2 && |
ece3c67f JH |
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 && | |
816366e2 | 29 | git commit -m "Side changes #3 with \\n backslash-n in it." && |
ece3c67f JH |
30 | |
31 | git checkout master && | |
982b64e4 JH |
32 | git diff-tree -p C2 | git apply --index && |
33 | git commit -m "Master accepts moral equivalent of #2" | |
ece3c67f JH |
34 | |
35 | ' | |
36 | ||
37 | test_expect_success "format-patch --ignore-if-in-upstream" ' | |
38 | ||
39 | git format-patch --stdout master..side >patch0 && | |
40 | cnt=`grep "^From " patch0 | wc -l` && | |
8780bd8f | 41 | test $cnt = 3 |
ece3c67f JH |
42 | |
43 | ' | |
44 | ||
45 | test_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` && | |
8780bd8f | 50 | test $cnt = 2 |
ece3c67f JH |
51 | |
52 | ' | |
53 | ||
54 | test_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` && | |
8780bd8f | 59 | test $cnt = 2 |
ece3c67f JH |
60 | ' |
61 | ||
62 | test_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` && | |
8780bd8f | 67 | test $cnt = 2 |
ece3c67f JH |
68 | ' |
69 | ||
816366e2 JH |
70 | test_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 | ||
76 | test_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 | ||
83 | test_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 | ||
a8d8173e DB |
89 | test_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 && | |
1ba08363 | 96 | sed -e "/^$/q" patch2 > hdrs2 && |
a8d8173e DB |
97 | grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs2 && |
98 | grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs2 | |
3b2eb186 | 99 | |
a8d8173e DB |
100 | ' |
101 | ||
7d22708b | 102 | test_expect_success 'extra headers without newlines' ' |
a8d8173e DB |
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 && | |
1ba08363 | 107 | sed -e "/^$/q" patch3 > hdrs3 && |
a8d8173e DB |
108 | grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs3 && |
109 | grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs3 | |
3b2eb186 | 110 | |
a8d8173e DB |
111 | ' |
112 | ||
3ee79d9f | 113 | test_expect_success 'extra headers with multiple To:s' ' |
a8d8173e DB |
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 && | |
1ba08363 | 118 | sed -e "/^$/q" patch4 > hdrs4 && |
a8d8173e DB |
119 | grep "^To: R. E. Cipient <rcipient@example.com>,$" hdrs4 && |
120 | grep "^ *S. E. Cipient <scipient@example.com>$" hdrs4 | |
121 | ' | |
122 | ||
736cc67d DB |
123 | test_expect_success 'additional command line cc' ' |
124 | ||
125 | git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" && | |
1ba08363 | 126 | git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch5 && |
736cc67d DB |
127 | grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch5 && |
128 | grep "^ *S. E. Cipient <scipient@example.com>$" patch5 | |
129 | ' | |
130 | ||
d7d9c2d0 MH |
131 | test_expect_success 'command line headers' ' |
132 | ||
133 | git config --unset-all format.headers && | |
134 | git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch6 && | |
135 | grep "^Cc: R. E. Cipient <rcipient@example.com>$" patch6 | |
136 | ' | |
137 | ||
138 | test_expect_success 'configuration headers and command line headers' ' | |
139 | ||
140 | git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" && | |
141 | git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch7 && | |
142 | grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch7 && | |
143 | grep "^ *S. E. Cipient <scipient@example.com>$" patch7 | |
144 | ' | |
145 | ||
7d812145 DB |
146 | test_expect_success 'multiple files' ' |
147 | ||
148 | rm -rf patches/ && | |
149 | git checkout side && | |
150 | git format-patch -o patches/ master && | |
151 | 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 | |
152 | ' | |
153 | ||
484cf6c3 TR |
154 | check_threading () { |
155 | expect="$1" && | |
156 | shift && | |
157 | (git format-patch --stdout "$@"; echo $? > status.out) | | |
158 | # Prints everything between the Message-ID and In-Reply-To, | |
159 | # and replaces all Message-ID-lookalikes by a sequence number | |
160 | perl -ne ' | |
161 | if (/^(message-id|references|in-reply-to)/i) { | |
162 | $printing = 1; | |
163 | } elsif (/^\S/) { | |
164 | $printing = 0; | |
165 | } | |
166 | if ($printing) { | |
167 | $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1}); | |
168 | for $k (keys %h) {s/$k/$h{$k}/}; | |
169 | print; | |
170 | } | |
171 | print "---\n" if /^From /i; | |
172 | ' > actual && | |
173 | test 0 = "$(cat status.out)" && | |
174 | test_cmp "$expect" actual | |
175 | } | |
176 | ||
177 | cat >> expect.no-threading <<EOF | |
178 | --- | |
179 | --- | |
180 | --- | |
181 | EOF | |
182 | ||
183 | test_expect_success 'no threading' ' | |
7d812145 | 184 | git checkout side && |
484cf6c3 | 185 | check_threading expect.no-threading master |
7d812145 DB |
186 | ' |
187 | ||
484cf6c3 TR |
188 | cat > expect.thread <<EOF |
189 | --- | |
190 | Message-Id: <0> | |
191 | --- | |
192 | Message-Id: <1> | |
193 | In-Reply-To: <0> | |
194 | References: <0> | |
195 | --- | |
196 | Message-Id: <2> | |
197 | In-Reply-To: <0> | |
198 | References: <0> | |
199 | EOF | |
7d812145 | 200 | |
484cf6c3 TR |
201 | test_expect_success 'thread' ' |
202 | check_threading expect.thread --thread master | |
7d812145 DB |
203 | ' |
204 | ||
484cf6c3 TR |
205 | cat > expect.in-reply-to <<EOF |
206 | --- | |
207 | Message-Id: <0> | |
208 | In-Reply-To: <1> | |
209 | References: <1> | |
210 | --- | |
211 | Message-Id: <2> | |
212 | In-Reply-To: <1> | |
213 | References: <1> | |
214 | --- | |
215 | Message-Id: <3> | |
216 | In-Reply-To: <1> | |
217 | References: <1> | |
218 | EOF | |
a5a27c79 | 219 | |
484cf6c3 TR |
220 | test_expect_success 'thread in-reply-to' ' |
221 | check_threading expect.in-reply-to --in-reply-to="<test.message>" \ | |
222 | --thread master | |
a5a27c79 DB |
223 | ' |
224 | ||
484cf6c3 TR |
225 | cat > expect.cover-letter <<EOF |
226 | --- | |
227 | Message-Id: <0> | |
228 | --- | |
229 | Message-Id: <1> | |
230 | In-Reply-To: <0> | |
231 | References: <0> | |
232 | --- | |
233 | Message-Id: <2> | |
234 | In-Reply-To: <0> | |
235 | References: <0> | |
236 | --- | |
237 | Message-Id: <3> | |
238 | In-Reply-To: <0> | |
239 | References: <0> | |
240 | EOF | |
a5a27c79 | 241 | |
484cf6c3 TR |
242 | test_expect_success 'thread cover-letter' ' |
243 | check_threading expect.cover-letter --cover-letter --thread master | |
244 | ' | |
245 | ||
246 | cat > expect.cl-irt <<EOF | |
247 | --- | |
248 | Message-Id: <0> | |
249 | In-Reply-To: <1> | |
250 | References: <1> | |
251 | --- | |
252 | Message-Id: <2> | |
2175c10d | 253 | In-Reply-To: <0> |
484cf6c3 | 254 | References: <1> |
2175c10d | 255 | <0> |
484cf6c3 TR |
256 | --- |
257 | Message-Id: <3> | |
2175c10d | 258 | In-Reply-To: <0> |
484cf6c3 | 259 | References: <1> |
2175c10d | 260 | <0> |
484cf6c3 TR |
261 | --- |
262 | Message-Id: <4> | |
2175c10d | 263 | In-Reply-To: <0> |
484cf6c3 | 264 | References: <1> |
2175c10d | 265 | <0> |
484cf6c3 TR |
266 | EOF |
267 | ||
268 | test_expect_success 'thread cover-letter in-reply-to' ' | |
269 | check_threading expect.cl-irt --cover-letter \ | |
270 | --in-reply-to="<test.message>" --thread master | |
a5a27c79 DB |
271 | ' |
272 | ||
30984ed2 TR |
273 | test_expect_success 'thread explicit shallow' ' |
274 | check_threading expect.cl-irt --cover-letter \ | |
275 | --in-reply-to="<test.message>" --thread=shallow master | |
276 | ' | |
277 | ||
278 | cat > expect.deep <<EOF | |
279 | --- | |
280 | Message-Id: <0> | |
281 | --- | |
282 | Message-Id: <1> | |
283 | In-Reply-To: <0> | |
284 | References: <0> | |
285 | --- | |
286 | Message-Id: <2> | |
287 | In-Reply-To: <1> | |
288 | References: <0> | |
289 | <1> | |
290 | EOF | |
291 | ||
292 | test_expect_success 'thread deep' ' | |
293 | check_threading expect.deep --thread=deep master | |
294 | ' | |
295 | ||
296 | cat > expect.deep-irt <<EOF | |
297 | --- | |
298 | Message-Id: <0> | |
299 | In-Reply-To: <1> | |
300 | References: <1> | |
301 | --- | |
302 | Message-Id: <2> | |
303 | In-Reply-To: <0> | |
304 | References: <1> | |
305 | <0> | |
306 | --- | |
307 | Message-Id: <3> | |
308 | In-Reply-To: <2> | |
309 | References: <1> | |
310 | <0> | |
311 | <2> | |
312 | EOF | |
313 | ||
314 | test_expect_success 'thread deep in-reply-to' ' | |
315 | check_threading expect.deep-irt --thread=deep \ | |
316 | --in-reply-to="<test.message>" master | |
317 | ' | |
318 | ||
319 | cat > expect.deep-cl <<EOF | |
320 | --- | |
321 | Message-Id: <0> | |
322 | --- | |
323 | Message-Id: <1> | |
324 | In-Reply-To: <0> | |
325 | References: <0> | |
326 | --- | |
327 | Message-Id: <2> | |
328 | In-Reply-To: <1> | |
329 | References: <0> | |
330 | <1> | |
331 | --- | |
332 | Message-Id: <3> | |
333 | In-Reply-To: <2> | |
334 | References: <0> | |
335 | <1> | |
336 | <2> | |
337 | EOF | |
338 | ||
339 | test_expect_success 'thread deep cover-letter' ' | |
340 | check_threading expect.deep-cl --cover-letter --thread=deep master | |
341 | ' | |
342 | ||
343 | cat > expect.deep-cl-irt <<EOF | |
344 | --- | |
345 | Message-Id: <0> | |
346 | In-Reply-To: <1> | |
347 | References: <1> | |
348 | --- | |
349 | Message-Id: <2> | |
350 | In-Reply-To: <0> | |
351 | References: <1> | |
352 | <0> | |
353 | --- | |
354 | Message-Id: <3> | |
355 | In-Reply-To: <2> | |
356 | References: <1> | |
357 | <0> | |
358 | <2> | |
359 | --- | |
360 | Message-Id: <4> | |
361 | In-Reply-To: <3> | |
362 | References: <1> | |
363 | <0> | |
364 | <2> | |
365 | <3> | |
366 | EOF | |
367 | ||
368 | test_expect_success 'thread deep cover-letter in-reply-to' ' | |
369 | check_threading expect.deep-cl-irt --cover-letter \ | |
370 | --in-reply-to="<test.message>" --thread=deep master | |
371 | ' | |
372 | ||
373 | test_expect_success 'thread via config' ' | |
374 | git config format.thread true && | |
375 | check_threading expect.thread master | |
376 | ' | |
377 | ||
378 | test_expect_success 'thread deep via config' ' | |
379 | git config format.thread deep && | |
380 | check_threading expect.deep master | |
381 | ' | |
382 | ||
383 | test_expect_success 'thread config + override' ' | |
384 | git config format.thread deep && | |
385 | check_threading expect.thread --thread master | |
386 | ' | |
387 | ||
388 | test_expect_success 'thread config + --no-thread' ' | |
389 | git config format.thread deep && | |
390 | check_threading expect.no-threading --no-thread master | |
391 | ' | |
392 | ||
7d812145 DB |
393 | test_expect_success 'excessive subject' ' |
394 | ||
395 | rm -rf patches/ && | |
396 | git checkout side && | |
397 | for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file && | |
398 | git update-index file && | |
399 | 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." && | |
400 | git format-patch -o patches/ master..side && | |
401 | ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch | |
402 | ' | |
403 | ||
5d02294c JS |
404 | test_expect_success 'cover-letter inherits diff options' ' |
405 | ||
406 | git mv file foo && | |
407 | git commit -m foo && | |
408 | git format-patch --cover-letter -1 && | |
409 | ! grep "file => foo .* 0 *$" 0000-cover-letter.patch && | |
410 | git format-patch --cover-letter -1 -M && | |
411 | grep "file => foo .* 0 *$" 0000-cover-letter.patch | |
412 | ||
413 | ' | |
859c4fbe JS |
414 | |
415 | cat > expect << EOF | |
416 | This is an excessively long subject line for a message due to the | |
417 | habit some projects have of not having a short, one-line subject at | |
418 | the start of the commit message, but rather sticking a whole | |
419 | paragraph right at the start as the only thing in the commit | |
420 | message. It had better not become the filename for the patch. | |
421 | foo | |
422 | ||
423 | EOF | |
424 | ||
425 | test_expect_success 'shortlog of cover-letter wraps overly-long onelines' ' | |
426 | ||
427 | git format-patch --cover-letter -2 && | |
428 | sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output && | |
3af82863 | 429 | test_cmp expect output |
859c4fbe JS |
430 | |
431 | ' | |
432 | ||
68daa64d JK |
433 | cat > expect << EOF |
434 | --- | |
435 | file | 16 ++++++++++++++++ | |
436 | 1 files changed, 16 insertions(+), 0 deletions(-) | |
437 | ||
438 | diff --git a/file b/file | |
439 | index 40f36c6..2dc5c23 100644 | |
440 | --- a/file | |
441 | +++ b/file | |
442 | @@ -13,4 +13,20 @@ C | |
443 | 10 | |
444 | D | |
445 | E | |
446 | F | |
447 | +5 | |
448 | EOF | |
449 | ||
450 | test_expect_success 'format-patch respects -U' ' | |
451 | ||
452 | git format-patch -U4 -2 && | |
453 | sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && | |
454 | test_cmp expect output | |
455 | ||
456 | ' | |
457 | ||
1d46f2ea JK |
458 | cat > expect << EOF |
459 | ||
460 | diff --git a/file b/file | |
461 | index 40f36c6..2dc5c23 100644 | |
462 | --- a/file | |
463 | +++ b/file | |
464 | @@ -14,3 +14,19 @@ C | |
465 | D | |
466 | E | |
467 | F | |
468 | +5 | |
469 | EOF | |
470 | ||
471 | test_expect_success 'format-patch -p suppresses stat' ' | |
472 | ||
473 | git format-patch -p -2 && | |
474 | sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && | |
475 | test_cmp expect output | |
476 | ||
477 | ' | |
478 | ||
9800a754 JH |
479 | test_expect_success 'format-patch from a subdirectory (1)' ' |
480 | filename=$( | |
481 | rm -rf sub && | |
482 | mkdir -p sub/dir && | |
483 | cd sub/dir && | |
484 | git format-patch -1 | |
485 | ) && | |
486 | case "$filename" in | |
487 | 0*) | |
488 | ;; # ok | |
489 | *) | |
490 | echo "Oops? $filename" | |
491 | false | |
492 | ;; | |
493 | esac && | |
494 | test -f "$filename" | |
495 | ' | |
496 | ||
497 | test_expect_success 'format-patch from a subdirectory (2)' ' | |
498 | filename=$( | |
499 | rm -rf sub && | |
500 | mkdir -p sub/dir && | |
501 | cd sub/dir && | |
502 | git format-patch -1 -o .. | |
503 | ) && | |
504 | case "$filename" in | |
505 | ../0*) | |
506 | ;; # ok | |
507 | *) | |
508 | echo "Oops? $filename" | |
509 | false | |
510 | ;; | |
511 | esac && | |
512 | basename=$(expr "$filename" : ".*/\(.*\)") && | |
513 | test -f "sub/$basename" | |
514 | ' | |
515 | ||
516 | test_expect_success 'format-patch from a subdirectory (3)' ' | |
9800a754 JH |
517 | rm -f 0* && |
518 | filename=$( | |
519 | rm -rf sub && | |
520 | mkdir -p sub/dir && | |
521 | cd sub/dir && | |
91c8b825 | 522 | git format-patch -1 -o "$TRASH_DIRECTORY" |
9800a754 JH |
523 | ) && |
524 | basename=$(expr "$filename" : ".*/\(.*\)") && | |
525 | test -f "$basename" | |
526 | ' | |
527 | ||
f044fe2d SB |
528 | test_expect_success 'format-patch --in-reply-to' ' |
529 | git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 && | |
530 | grep "^In-Reply-To: <baz@foo.bar>" patch8 && | |
531 | grep "^References: <baz@foo.bar>" patch8 | |
532 | ' | |
533 | ||
534 | test_expect_success 'format-patch --signoff' ' | |
535 | git format-patch -1 --signoff --stdout | | |
536 | grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" | |
537 | ' | |
538 | ||
ece3c67f | 539 | test_done |