Merge branch 'bs/maint-1.6.0-tree-walk-prefix' into maint
[git] / t / t4014-format-patch.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
5
6 test_description='various format-patch tests'
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 &&
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
39 test_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
47 test_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
56 test_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
64 test_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
72 test_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
78 test_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
85 test_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
91 test_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
104 test_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
115 test_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
125 test_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
133 test_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
141 test_expect_success 'thread' '
142
143         rm -rf patches/ &&
144         git checkout side &&
145         git format-patch --thread -o patches/ master &&
146         FIRST_MID=$(grep "Message-Id:" patches/0001-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") &&
147         for i in patches/0002-* patches/0003-*
148         do
149           grep "References: $FIRST_MID" $i &&
150           grep "In-Reply-To: $FIRST_MID" $i || break
151         done
152 '
153
154 test_expect_success 'thread in-reply-to' '
155
156         rm -rf patches/ &&
157         git checkout side &&
158         git format-patch --in-reply-to="<test.message>" --thread -o patches/ master &&
159         FIRST_MID="<test.message>" &&
160         for i in patches/*
161         do
162           grep "References: $FIRST_MID" $i &&
163           grep "In-Reply-To: $FIRST_MID" $i || break
164         done
165 '
166
167 test_expect_success 'thread cover-letter' '
168
169         rm -rf patches/ &&
170         git checkout side &&
171         git format-patch --cover-letter --thread -o patches/ master &&
172         FIRST_MID=$(grep "Message-Id:" patches/0000-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") &&
173         for i in patches/0001-* patches/0002-* patches/0003-*
174         do
175           grep "References: $FIRST_MID" $i &&
176           grep "In-Reply-To: $FIRST_MID" $i || break
177         done
178 '
179
180 test_expect_success 'thread cover-letter in-reply-to' '
181
182         rm -rf patches/ &&
183         git checkout side &&
184         git format-patch --cover-letter --in-reply-to="<test.message>" --thread -o patches/ master &&
185         FIRST_MID="<test.message>" &&
186         for i in patches/*
187         do
188           grep "References: $FIRST_MID" $i &&
189           grep "In-Reply-To: $FIRST_MID" $i || break
190         done
191 '
192
193 test_expect_success 'excessive subject' '
194
195         rm -rf patches/ &&
196         git checkout side &&
197         for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
198         git update-index file &&
199         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." &&
200         git format-patch -o patches/ master..side &&
201         ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
202 '
203
204 test_expect_success 'cover-letter inherits diff options' '
205
206         git mv file foo &&
207         git commit -m foo &&
208         git format-patch --cover-letter -1 &&
209         ! grep "file => foo .* 0 *$" 0000-cover-letter.patch &&
210         git format-patch --cover-letter -1 -M &&
211         grep "file => foo .* 0 *$" 0000-cover-letter.patch
212
213 '
214
215 cat > expect << EOF
216   This is an excessively long subject line for a message due to the
217     habit some projects have of not having a short, one-line subject at
218     the start of the commit message, but rather sticking a whole
219     paragraph right at the start as the only thing in the commit
220     message. It had better not become the filename for the patch.
221   foo
222
223 EOF
224
225 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
226
227         git format-patch --cover-letter -2 &&
228         sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output &&
229         test_cmp expect output
230
231 '
232
233 cat > expect << EOF
234 ---
235  file |   16 ++++++++++++++++
236  1 files changed, 16 insertions(+), 0 deletions(-)
237
238 diff --git a/file b/file
239 index 40f36c6..2dc5c23 100644
240 --- a/file
241 +++ b/file
242 @@ -13,4 +13,20 @@ C
243  10
244  D
245  E
246  F
247 +5
248 EOF
249
250 test_expect_success 'format-patch respects -U' '
251
252         git format-patch -U4 -2 &&
253         sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
254         test_cmp expect output
255
256 '
257
258 test_expect_success 'format-patch from a subdirectory (1)' '
259         filename=$(
260                 rm -rf sub &&
261                 mkdir -p sub/dir &&
262                 cd sub/dir &&
263                 git format-patch -1
264         ) &&
265         case "$filename" in
266         0*)
267                 ;; # ok
268         *)
269                 echo "Oops? $filename"
270                 false
271                 ;;
272         esac &&
273         test -f "$filename"
274 '
275
276 test_expect_success 'format-patch from a subdirectory (2)' '
277         filename=$(
278                 rm -rf sub &&
279                 mkdir -p sub/dir &&
280                 cd sub/dir &&
281                 git format-patch -1 -o ..
282         ) &&
283         case "$filename" in
284         ../0*)
285                 ;; # ok
286         *)
287                 echo "Oops? $filename"
288                 false
289                 ;;
290         esac &&
291         basename=$(expr "$filename" : ".*/\(.*\)") &&
292         test -f "sub/$basename"
293 '
294
295 test_expect_success 'format-patch from a subdirectory (3)' '
296         here="$TEST_DIRECTORY/$test" &&
297         rm -f 0* &&
298         filename=$(
299                 rm -rf sub &&
300                 mkdir -p sub/dir &&
301                 cd sub/dir &&
302                 git format-patch -1 -o "$here"
303         ) &&
304         basename=$(expr "$filename" : ".*/\(.*\)") &&
305         test -f "$basename"
306 '
307
308 test_done