f187d15e328aa43f3d7a7b9030158e0128cc4812
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
6 test_description='various format-patch tests'
8 . ./test-lib.sh
10 test_expect_success setup '
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 &&
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" &&
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 &&
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." &&
31 git checkout master &&
32 git diff-tree -p C2 | git apply --index &&
33 git commit -m "Master accepts moral equivalent of #2"
35 '
37 test_expect_success "format-patch --ignore-if-in-upstream" '
39 git format-patch --stdout master..side >patch0 &&
40 cnt=`grep "^From " patch0 | wc -l` &&
41 test $cnt = 3
43 '
45 test_expect_success "format-patch --ignore-if-in-upstream" '
47 git format-patch --stdout \
48 --ignore-if-in-upstream master..side >patch1 &&
49 cnt=`grep "^From " patch1 | wc -l` &&
50 test $cnt = 2
52 '
54 test_expect_success "format-patch result applies" '
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 '
62 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
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 '
70 test_expect_success 'commit did not screw up the log message' '
72 git cat-file commit side | grep "^Side .* with .* backslash-n"
74 '
76 test_expect_success 'format-patch did not screw up the log message' '
78 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
79 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
81 '
83 test_expect_success 'replay did not screw up the log message' '
85 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
87 '
89 test_expect_success 'extra headers' '
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
100 '
102 test_expect_success 'extra headers without newlines' '
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
111 '
113 test_expect_success 'extra headers with multiple To:s' '
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 '
123 test_expect_success 'additional command line cc' '
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 '
131 test_expect_success 'multiple files' '
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 '
139 check_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 }
162 cat >> expect.no-threading <<EOF
163 ---
164 ---
165 ---
166 EOF
168 test_expect_success 'no threading' '
169 git checkout side &&
170 check_threading expect.no-threading master
171 '
173 cat > expect.thread <<EOF
174 ---
175 Message-Id: <0>
176 ---
177 Message-Id: <1>
178 In-Reply-To: <0>
179 References: <0>
180 ---
181 Message-Id: <2>
182 In-Reply-To: <0>
183 References: <0>
184 EOF
186 test_expect_success 'thread' '
187 check_threading expect.thread --thread master
188 '
190 cat > expect.in-reply-to <<EOF
191 ---
192 Message-Id: <0>
193 In-Reply-To: <1>
194 References: <1>
195 ---
196 Message-Id: <2>
197 In-Reply-To: <1>
198 References: <1>
199 ---
200 Message-Id: <3>
201 In-Reply-To: <1>
202 References: <1>
203 EOF
205 test_expect_success 'thread in-reply-to' '
206 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
207 --thread master
208 '
210 cat > expect.cover-letter <<EOF
211 ---
212 Message-Id: <0>
213 ---
214 Message-Id: <1>
215 In-Reply-To: <0>
216 References: <0>
217 ---
218 Message-Id: <2>
219 In-Reply-To: <0>
220 References: <0>
221 ---
222 Message-Id: <3>
223 In-Reply-To: <0>
224 References: <0>
225 EOF
227 test_expect_success 'thread cover-letter' '
228 check_threading expect.cover-letter --cover-letter --thread master
229 '
231 cat > expect.cl-irt <<EOF
232 ---
233 Message-Id: <0>
234 In-Reply-To: <1>
235 References: <1>
236 ---
237 Message-Id: <2>
238 In-Reply-To: <0>
239 References: <1>
240 <0>
241 ---
242 Message-Id: <3>
243 In-Reply-To: <0>
244 References: <1>
245 <0>
246 ---
247 Message-Id: <4>
248 In-Reply-To: <0>
249 References: <1>
250 <0>
251 EOF
253 test_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 '
258 test_expect_success 'thread explicit shallow' '
259 check_threading expect.cl-irt --cover-letter \
260 --in-reply-to="<test.message>" --thread=shallow master
261 '
263 cat > expect.deep <<EOF
264 ---
265 Message-Id: <0>
266 ---
267 Message-Id: <1>
268 In-Reply-To: <0>
269 References: <0>
270 ---
271 Message-Id: <2>
272 In-Reply-To: <1>
273 References: <0>
274 <1>
275 EOF
277 test_expect_success 'thread deep' '
278 check_threading expect.deep --thread=deep master
279 '
281 cat > expect.deep-irt <<EOF
282 ---
283 Message-Id: <0>
284 In-Reply-To: <1>
285 References: <1>
286 ---
287 Message-Id: <2>
288 In-Reply-To: <0>
289 References: <1>
290 <0>
291 ---
292 Message-Id: <3>
293 In-Reply-To: <2>
294 References: <1>
295 <0>
296 <2>
297 EOF
299 test_expect_success 'thread deep in-reply-to' '
300 check_threading expect.deep-irt --thread=deep \
301 --in-reply-to="<test.message>" master
302 '
304 cat > expect.deep-cl <<EOF
305 ---
306 Message-Id: <0>
307 ---
308 Message-Id: <1>
309 In-Reply-To: <0>
310 References: <0>
311 ---
312 Message-Id: <2>
313 In-Reply-To: <1>
314 References: <0>
315 <1>
316 ---
317 Message-Id: <3>
318 In-Reply-To: <2>
319 References: <0>
320 <1>
321 <2>
322 EOF
324 test_expect_success 'thread deep cover-letter' '
325 check_threading expect.deep-cl --cover-letter --thread=deep master
326 '
328 cat > expect.deep-cl-irt <<EOF
329 ---
330 Message-Id: <0>
331 In-Reply-To: <1>
332 References: <1>
333 ---
334 Message-Id: <2>
335 In-Reply-To: <0>
336 References: <1>
337 <0>
338 ---
339 Message-Id: <3>
340 In-Reply-To: <2>
341 References: <1>
342 <0>
343 <2>
344 ---
345 Message-Id: <4>
346 In-Reply-To: <3>
347 References: <1>
348 <0>
349 <2>
350 <3>
351 EOF
353 test_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 '
358 test_expect_success 'thread via config' '
359 git config format.thread true &&
360 check_threading expect.thread master
361 '
363 test_expect_success 'thread deep via config' '
364 git config format.thread deep &&
365 check_threading expect.deep master
366 '
368 test_expect_success 'thread config + override' '
369 git config format.thread deep &&
370 check_threading expect.thread --thread master
371 '
373 test_expect_success 'thread config + --no-thread' '
374 git config format.thread deep &&
375 check_threading expect.no-threading --no-thread master
376 '
378 test_expect_success 'excessive subject' '
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 '
389 test_expect_success 'cover-letter inherits diff options' '
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
398 '
400 cat > 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
408 EOF
410 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
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
416 '
418 cat > expect << EOF
419 ---
420 file | 16 ++++++++++++++++
421 1 files changed, 16 insertions(+), 0 deletions(-)
423 diff --git a/file b/file
424 index 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
433 EOF
435 test_expect_success 'format-patch respects -U' '
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
441 '
443 test_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 '
461 test_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 '
480 test_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 '
493 test_done