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 chmod +x elif &&
20 git update-index file elif &&
21 git update-index --chmod=+x elif &&
22 git commit -m "Side changes #1" &&
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 &&
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." &&
33 git checkout master &&
34 git diff-tree -p C2 | git apply --index &&
35 git commit -m "Master accepts moral equivalent of #2"
37 '
39 test_expect_success "format-patch --ignore-if-in-upstream" '
41 git format-patch --stdout master..side >patch0 &&
42 cnt=`grep "^From " patch0 | wc -l` &&
43 test $cnt = 3
45 '
47 test_expect_success "format-patch --ignore-if-in-upstream" '
49 git format-patch --stdout \
50 --ignore-if-in-upstream master..side >patch1 &&
51 cnt=`grep "^From " patch1 | wc -l` &&
52 test $cnt = 2
54 '
56 test_expect_success "format-patch result applies" '
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 '
64 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
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 '
72 test_expect_success 'commit did not screw up the log message' '
74 git cat-file commit side | grep "^Side .* with .* backslash-n"
76 '
78 test_expect_success 'format-patch did not screw up the log message' '
80 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
81 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
83 '
85 test_expect_success 'replay did not screw up the log message' '
87 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
89 '
91 test_expect_success 'extra headers' '
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
102 '
104 test_expect_success 'extra headers without newlines' '
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
113 '
115 test_expect_success 'extra headers with multiple To:s' '
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 '
125 test_expect_success 'additional command line cc' '
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 '
133 test_expect_success 'multiple files' '
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 '
141 check_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 }
164 cat >> expect.no-threading <<EOF
165 ---
166 ---
167 ---
168 EOF
170 test_expect_success 'no threading' '
171 git checkout side &&
172 check_threading expect.no-threading master
173 '
175 cat > expect.thread <<EOF
176 ---
177 Message-Id: <0>
178 ---
179 Message-Id: <1>
180 In-Reply-To: <0>
181 References: <0>
182 ---
183 Message-Id: <2>
184 In-Reply-To: <0>
185 References: <0>
186 EOF
188 test_expect_success 'thread' '
189 check_threading expect.thread --thread master
190 '
192 cat > expect.in-reply-to <<EOF
193 ---
194 Message-Id: <0>
195 In-Reply-To: <1>
196 References: <1>
197 ---
198 Message-Id: <2>
199 In-Reply-To: <1>
200 References: <1>
201 ---
202 Message-Id: <3>
203 In-Reply-To: <1>
204 References: <1>
205 EOF
207 test_expect_success 'thread in-reply-to' '
208 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
209 --thread master
210 '
212 cat > expect.cover-letter <<EOF
213 ---
214 Message-Id: <0>
215 ---
216 Message-Id: <1>
217 In-Reply-To: <0>
218 References: <0>
219 ---
220 Message-Id: <2>
221 In-Reply-To: <0>
222 References: <0>
223 ---
224 Message-Id: <3>
225 In-Reply-To: <0>
226 References: <0>
227 EOF
229 test_expect_success 'thread cover-letter' '
230 check_threading expect.cover-letter --cover-letter --thread master
231 '
233 cat > expect.cl-irt <<EOF
234 ---
235 Message-Id: <0>
236 In-Reply-To: <1>
237 References: <1>
238 ---
239 Message-Id: <2>
240 In-Reply-To: <1>
241 References: <1>
242 ---
243 Message-Id: <3>
244 In-Reply-To: <1>
245 References: <1>
246 ---
247 Message-Id: <4>
248 In-Reply-To: <1>
249 References: <1>
250 EOF
252 test_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 '
257 test_expect_success 'excessive subject' '
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 '
268 test_expect_success 'cover-letter inherits diff options' '
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
277 '
279 cat > 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
287 EOF
289 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
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
295 '
297 cat > expect << EOF
298 ---
299 file | 16 ++++++++++++++++
300 1 files changed, 16 insertions(+), 0 deletions(-)
302 diff --git a/file b/file
303 index 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
312 EOF
314 test_expect_success 'format-patch respects -U' '
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
320 '
322 test_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 '
340 test_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 '
359 test_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 '
372 test_done