@@ -126,6 +126,305 @@ test_expect_success 'with multiline title in the message' '
126126 test_cmp expected actual
127127'
128128
129+ test_expect_success ' with non-trailer lines mixed with Signed-off-by' '
130+ cat >patch <<-\EOF &&
131+
132+ this is not a trailer
133+ this is not a trailer
134+ Signed-off-by: a <a@example.com>
135+ this is not a trailer
136+ EOF
137+ cat >expected <<-\EOF &&
138+
139+ this is not a trailer
140+ this is not a trailer
141+ Signed-off-by: a <a@example.com>
142+ this is not a trailer
143+ token: value
144+ EOF
145+ git interpret-trailers --trailer "token: value" patch >actual &&
146+ test_cmp expected actual
147+ '
148+
149+ test_expect_success ' with non-trailer lines mixed with cherry picked from' '
150+ cat >patch <<-\EOF &&
151+
152+ this is not a trailer
153+ this is not a trailer
154+ (cherry picked from commit x)
155+ this is not a trailer
156+ EOF
157+ cat >expected <<-\EOF &&
158+
159+ this is not a trailer
160+ this is not a trailer
161+ (cherry picked from commit x)
162+ this is not a trailer
163+ token: value
164+ EOF
165+ git interpret-trailers --trailer "token: value" patch >actual &&
166+ test_cmp expected actual
167+ '
168+
169+ test_expect_success ' with non-trailer lines mixed with a configured trailer' '
170+ cat >patch <<-\EOF &&
171+
172+ this is not a trailer
173+ this is not a trailer
174+ My-trailer: x
175+ this is not a trailer
176+ EOF
177+ cat >expected <<-\EOF &&
178+
179+ this is not a trailer
180+ this is not a trailer
181+ My-trailer: x
182+ this is not a trailer
183+ token: value
184+ EOF
185+ test_config trailer.my.key "My-trailer: " &&
186+ git interpret-trailers --trailer "token: value" patch >actual &&
187+ test_cmp expected actual
188+ '
189+
190+ test_expect_success ' with non-trailer lines mixed with a non-configured trailer' '
191+ cat >patch <<-\EOF &&
192+
193+ this is not a trailer
194+ this is not a trailer
195+ I-am-not-configured: x
196+ this is not a trailer
197+ EOF
198+ cat >expected <<-\EOF &&
199+
200+ this is not a trailer
201+ this is not a trailer
202+ I-am-not-configured: x
203+ this is not a trailer
204+
205+ token: value
206+ EOF
207+ test_config trailer.my.key "My-trailer: " &&
208+ git interpret-trailers --trailer "token: value" patch >actual &&
209+ test_cmp expected actual
210+ '
211+
212+ test_expect_success ' with all non-configured trailers' '
213+ cat >patch <<-\EOF &&
214+
215+ I-am-not-configured: x
216+ I-am-also-not-configured: x
217+ EOF
218+ cat >expected <<-\EOF &&
219+
220+ I-am-not-configured: x
221+ I-am-also-not-configured: x
222+ token: value
223+ EOF
224+ test_config trailer.my.key "My-trailer: " &&
225+ git interpret-trailers --trailer "token: value" patch >actual &&
226+ test_cmp expected actual
227+ '
228+
229+ test_expect_success ' with non-trailer lines only' '
230+ cat >patch <<-\EOF &&
231+
232+ this is not a trailer
233+ EOF
234+ cat >expected <<-\EOF &&
235+
236+ this is not a trailer
237+
238+ token: value
239+ EOF
240+ git interpret-trailers --trailer "token: value" patch >actual &&
241+ test_cmp expected actual
242+ '
243+
244+ test_expect_success ' line with leading whitespace is not trailer' '
245+ q_to_tab >patch <<-\EOF &&
246+
247+ Qtoken: value
248+ EOF
249+ q_to_tab >expected <<-\EOF &&
250+
251+ Qtoken: value
252+
253+ token: value
254+ EOF
255+ git interpret-trailers --trailer "token: value" patch >actual &&
256+ test_cmp expected actual
257+ '
258+
259+ test_expect_success ' multiline field treated as one trailer for 25% check' '
260+ q_to_tab >patch <<-\EOF &&
261+
262+ Signed-off-by: a <a@example.com>
263+ name: value on
264+ Qmultiple lines
265+ this is not a trailer
266+ this is not a trailer
267+ this is not a trailer
268+ this is not a trailer
269+ this is not a trailer
270+ this is not a trailer
271+ EOF
272+ q_to_tab >expected <<-\EOF &&
273+
274+ Signed-off-by: a <a@example.com>
275+ name: value on
276+ Qmultiple lines
277+ this is not a trailer
278+ this is not a trailer
279+ this is not a trailer
280+ this is not a trailer
281+ this is not a trailer
282+ this is not a trailer
283+ name: value
284+ EOF
285+ git interpret-trailers --trailer "name: value" patch >actual &&
286+ test_cmp expected actual
287+ '
288+
289+ test_expect_success ' multiline field treated as atomic for placement' '
290+ q_to_tab >patch <<-\EOF &&
291+
292+ another: trailer
293+ name: value on
294+ Qmultiple lines
295+ another: trailer
296+ EOF
297+ q_to_tab >expected <<-\EOF &&
298+
299+ another: trailer
300+ name: value on
301+ Qmultiple lines
302+ name: value
303+ another: trailer
304+ EOF
305+ test_config trailer.name.where after &&
306+ git interpret-trailers --trailer "name: value" patch >actual &&
307+ test_cmp expected actual
308+ '
309+
310+ test_expect_success ' multiline field treated as atomic for replacement' '
311+ q_to_tab >patch <<-\EOF &&
312+
313+ another: trailer
314+ name: value on
315+ Qmultiple lines
316+ another: trailer
317+ EOF
318+ q_to_tab >expected <<-\EOF &&
319+
320+ another: trailer
321+ another: trailer
322+ name: value
323+ EOF
324+ test_config trailer.name.ifexists replace &&
325+ git interpret-trailers --trailer "name: value" patch >actual &&
326+ test_cmp expected actual
327+ '
328+
329+ test_expect_success ' multiline field treated as atomic for difference check' '
330+ q_to_tab >patch <<-\EOF &&
331+
332+ another: trailer
333+ name: first line
334+ Qsecond line
335+ another: trailer
336+ EOF
337+ test_config trailer.name.ifexists addIfDifferent &&
338+
339+ q_to_tab >trailer <<-\EOF &&
340+ name: first line
341+ Qsecond line
342+ EOF
343+ q_to_tab >expected <<-\EOF &&
344+
345+ another: trailer
346+ name: first line
347+ Qsecond line
348+ another: trailer
349+ EOF
350+ git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
351+ test_cmp expected actual &&
352+
353+ q_to_tab >trailer <<-\EOF &&
354+ name: first line
355+ QQQQQsecond line
356+ EOF
357+ q_to_tab >expected <<-\EOF &&
358+
359+ another: trailer
360+ name: first line
361+ Qsecond line
362+ another: trailer
363+ name: first line
364+ QQQQQsecond line
365+ EOF
366+ git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
367+ test_cmp expected actual &&
368+
369+ q_to_tab >trailer <<-\EOF &&
370+ name: first line *DIFFERENT*
371+ Qsecond line
372+ EOF
373+ q_to_tab >expected <<-\EOF &&
374+
375+ another: trailer
376+ name: first line
377+ Qsecond line
378+ another: trailer
379+ name: first line *DIFFERENT*
380+ Qsecond line
381+ EOF
382+ git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
383+ test_cmp expected actual
384+ '
385+
386+ test_expect_success ' multiline field treated as atomic for neighbor check' '
387+ q_to_tab >patch <<-\EOF &&
388+
389+ another: trailer
390+ name: first line
391+ Qsecond line
392+ another: trailer
393+ EOF
394+ test_config trailer.name.where after &&
395+ test_config trailer.name.ifexists addIfDifferentNeighbor &&
396+
397+ q_to_tab >trailer <<-\EOF &&
398+ name: first line
399+ Qsecond line
400+ EOF
401+ q_to_tab >expected <<-\EOF &&
402+
403+ another: trailer
404+ name: first line
405+ Qsecond line
406+ another: trailer
407+ EOF
408+ git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
409+ test_cmp expected actual &&
410+
411+ q_to_tab >trailer <<-\EOF &&
412+ name: first line
413+ QQQQQsecond line
414+ EOF
415+ q_to_tab >expected <<-\EOF &&
416+
417+ another: trailer
418+ name: first line
419+ Qsecond line
420+ name: first line
421+ QQQQQsecond line
422+ another: trailer
423+ EOF
424+ git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
425+ test_cmp expected actual
426+ '
427+
129428test_expect_success ' with config setup' '
130429 git config trailer.ack.key "Acked-by: " &&
131430 cat >expected <<-\EOF &&
0 commit comments