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