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 test_expect_success 'thread' '
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 '
154 test_expect_success 'thread in-reply-to' '
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 '
167 test_expect_success 'thread cover-letter' '
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 '
180 test_expect_success 'thread cover-letter in-reply-to' '
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 '
193 test_expect_success 'excessive subject' '
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 '
204 test_expect_success 'cover-letter inherits diff options' '
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
213 '
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
223 EOF
225 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
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
231 '
233 cat > expect << EOF
234 ---
235 file | 16 ++++++++++++++++
236 1 files changed, 16 insertions(+), 0 deletions(-)
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
250 test_expect_success 'format-patch respects -U' '
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
256 '
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 '
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 '
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 '
308 test_done