1#!/bin/sh
2#
3# Copyright (c) 2006, Junio C Hamano
4#
5
6test_description='fmt-merge-msg test'
7
8GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11. ./test-lib.sh
12. "$TEST_DIRECTORY/lib-gpg.sh"
13
14test_expect_success setup '
15	echo one >one &&
16	git add one &&
17	test_tick &&
18	git commit -m "Initial" &&
19
20	git clone . remote &&
21
22	echo uno >one &&
23	echo dos >two &&
24	git add two &&
25	test_tick &&
26	git commit -a -m "Second" &&
27
28	git checkout -b left &&
29
30	echo "c1" >one &&
31	test_tick &&
32	git commit -a -m "Common #1" &&
33
34	echo "c2" >one &&
35	test_tick &&
36	git commit -a -m "Common #2" &&
37
38	git branch right &&
39
40	echo "l3" >two &&
41	test_tick &&
42	GIT_COMMITTER_NAME="Another Committer" \
43	GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #3" &&
44
45	echo "l4" >two &&
46	test_tick &&
47	GIT_COMMITTER_NAME="Another Committer" \
48	GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #4" &&
49
50	echo "l5" >two &&
51	test_tick &&
52	GIT_COMMITTER_NAME="Another Committer" \
53	GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #5" &&
54	git tag tag-l5 &&
55
56	git checkout right &&
57
58	echo "r3" >three &&
59	git add three &&
60	test_tick &&
61	git commit -a -m "Right #3" &&
62	git tag tag-r3 &&
63
64	echo "r4" >three &&
65	test_tick &&
66	git commit -a -m "Right #4" &&
67
68	echo "r5" >three &&
69	test_tick &&
70	git commit -a -m "Right #5" &&
71
72	git checkout -b long &&
73	test_commit_bulk --start=0 --message=%s --filename=one 30 &&
74
75	git show-branch &&
76
77	apos="'\''"
78'
79
80test_expect_success GPG 'set up a signed tag' '
81	git tag -s -m signed-tag-msg signed-good-tag left
82'
83
84test_expect_success GPGSSH 'created ssh signed commit and tag' '
85	test_config gpg.format ssh &&
86	git checkout -b signed-ssh &&
87	touch file &&
88	git add file &&
89	git commit -m "ssh signed" -S"${GPGSSH_KEY_PRIMARY}" &&
90	git tag -s -u"${GPGSSH_KEY_PRIMARY}" -m signed-ssh-tag-msg signed-good-ssh-tag left &&
91	git tag -s -u"${GPGSSH_KEY_UNTRUSTED}" -m signed-ssh-tag-msg-untrusted signed-untrusted-ssh-tag left
92'
93
94test_expect_success 'message for merging local branch' '
95	echo "Merge branch ${apos}left${apos}" >expected &&
96
97	git checkout main &&
98	git fetch . left &&
99
100	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
101	test_cmp expected actual
102'
103
104test_expect_success GPG 'message for merging local tag signed by good key' '
105	git checkout main &&
106	git fetch . signed-good-tag &&
107	git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
108	grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
109	grep "^# gpg: Signature made" actual &&
110	grep "^# gpg: Good signature from" actual
111'
112
113test_expect_success GPG 'message for merging local tag signed by unknown key' '
114	git checkout main &&
115	git fetch . signed-good-tag &&
116	GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
117	grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
118	grep "^# gpg: Signature made" actual &&
119	grep -E "^# gpg: Can${apos}t check signature: (public key not found|No public key)" actual
120'
121
122test_expect_success GPGSSH 'message for merging local tag signed by good ssh key' '
123	test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
124	git checkout main &&
125	git fetch . signed-good-ssh-tag &&
126	git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
127	grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual &&
128	! grep "${GPGSSH_BAD_SIGNATURE}" actual
129'
130
131test_expect_success GPGSSH 'message for merging local tag signed by unknown ssh key' '
132	test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
133	git checkout main &&
134	git fetch . signed-untrusted-ssh-tag &&
135	git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
136	grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual &&
137	! grep "${GPGSSH_BAD_SIGNATURE}" actual &&
138	grep "${GPGSSH_KEY_NOT_TRUSTED}" actual
139'
140test_expect_success 'message for merging external branch' '
141	echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
142
143	git checkout main &&
144	git fetch "$(pwd)" left &&
145
146	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
147	test_cmp expected actual
148'
149
150test_expect_success '[merge] summary/log configuration' '
151	cat >expected <<-EOF &&
152	Merge branch ${apos}left${apos}
153
154	# By Another Author (3) and A U Thor (2)
155	# Via Another Committer
156	* left:
157	  Left #5
158	  Left #4
159	  Left #3
160	  Common #2
161	  Common #1
162	EOF
163
164	test_config merge.log true &&
165	test_unconfig merge.summary &&
166
167	git checkout main &&
168	test_tick &&
169	git fetch . left &&
170
171	git fmt-merge-msg <.git/FETCH_HEAD >actual1 &&
172
173	test_unconfig merge.log &&
174	test_config merge.summary true &&
175
176	git checkout main &&
177	test_tick &&
178	git fetch . left &&
179
180	git fmt-merge-msg <.git/FETCH_HEAD >actual2 &&
181
182	test_cmp expected actual1 &&
183	test_cmp expected actual2
184'
185
186test_expect_success 'setup FETCH_HEAD' '
187	git checkout main &&
188	test_tick &&
189	git fetch . left
190'
191
192test_expect_success 'merge.log=3 limits shortlog length' '
193	cat >expected <<-EOF &&
194	Merge branch ${apos}left${apos}
195
196	# By Another Author (3) and A U Thor (2)
197	# Via Another Committer
198	* left: (5 commits)
199	  Left #5
200	  Left #4
201	  Left #3
202	  ...
203	EOF
204
205	git -c merge.log=3 fmt-merge-msg <.git/FETCH_HEAD >actual &&
206	test_cmp expected actual
207'
208
209test_expect_success 'merge.log=5 shows all 5 commits' '
210	cat >expected <<-EOF &&
211	Merge branch ${apos}left${apos}
212
213	# By Another Author (3) and A U Thor (2)
214	# Via Another Committer
215	* left:
216	  Left #5
217	  Left #4
218	  Left #3
219	  Common #2
220	  Common #1
221	EOF
222
223	git -c merge.log=5 fmt-merge-msg <.git/FETCH_HEAD >actual &&
224	test_cmp expected actual
225'
226
227test_expect_success '--log=5 with custom comment character' '
228	cat >expected <<-EOF &&
229	Merge branch ${apos}left${apos}
230
231	x By Another Author (3) and A U Thor (2)
232	x Via Another Committer
233	* left:
234	  Left #5
235	  Left #4
236	  Left #3
237	  Common #2
238	  Common #1
239	EOF
240
241	git -c core.commentchar="x" fmt-merge-msg --log=5 <.git/FETCH_HEAD >actual &&
242	test_cmp expected actual
243'
244
245test_expect_success 'merge.log=0 disables shortlog' '
246	echo "Merge branch ${apos}left${apos}" >expected &&
247	git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual &&
248	test_cmp expected actual
249'
250
251test_expect_success '--log=3 limits shortlog length' '
252	cat >expected <<-EOF &&
253	Merge branch ${apos}left${apos}
254
255	# By Another Author (3) and A U Thor (2)
256	# Via Another Committer
257	* left: (5 commits)
258	  Left #5
259	  Left #4
260	  Left #3
261	  ...
262	EOF
263
264	git fmt-merge-msg --log=3 <.git/FETCH_HEAD >actual &&
265	test_cmp expected actual
266'
267
268test_expect_success '--log=5 shows all 5 commits' '
269	cat >expected <<-EOF &&
270	Merge branch ${apos}left${apos}
271
272	# By Another Author (3) and A U Thor (2)
273	# Via Another Committer
274	* left:
275	  Left #5
276	  Left #4
277	  Left #3
278	  Common #2
279	  Common #1
280	EOF
281
282	git fmt-merge-msg --log=5 <.git/FETCH_HEAD >actual &&
283	test_cmp expected actual
284'
285
286test_expect_success '--no-log disables shortlog' '
287	echo "Merge branch ${apos}left${apos}" >expected &&
288	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
289	test_cmp expected actual
290'
291
292test_expect_success '--log=0 disables shortlog' '
293	echo "Merge branch ${apos}left${apos}" >expected &&
294	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
295	test_cmp expected actual
296'
297
298test_expect_success 'fmt-merge-msg -m' '
299	echo "Sync with left" >expected &&
300	cat >expected.log <<-EOF &&
301	Sync with left
302
303	# By Another Author (3) and A U Thor (2)
304	# Via Another Committer
305	* ${apos}left${apos} of $(pwd):
306	  Left #5
307	  Left #4
308	  Left #3
309	  Common #2
310	  Common #1
311	EOF
312
313	test_unconfig merge.log &&
314	test_unconfig merge.summary &&
315	git checkout main &&
316	git fetch "$(pwd)" left &&
317	git fmt-merge-msg -m "Sync with left" <.git/FETCH_HEAD >actual &&
318	git fmt-merge-msg --log -m "Sync with left" \
319					<.git/FETCH_HEAD >actual.log &&
320	test_config merge.log true &&
321	git fmt-merge-msg -m "Sync with left" \
322					<.git/FETCH_HEAD >actual.log-config &&
323	git fmt-merge-msg --no-log -m "Sync with left" \
324					<.git/FETCH_HEAD >actual.nolog &&
325
326	test_cmp expected actual &&
327	test_cmp expected.log actual.log &&
328	test_cmp expected.log actual.log-config &&
329	test_cmp expected actual.nolog
330'
331
332test_expect_success 'setup: expected shortlog for two branches' '
333	cat >expected <<-EOF
334	Merge branches ${apos}left${apos} and ${apos}right${apos}
335
336	# By Another Author (3) and A U Thor (2)
337	# Via Another Committer
338	* left:
339	  Left #5
340	  Left #4
341	  Left #3
342	  Common #2
343	  Common #1
344
345	* right:
346	  Right #5
347	  Right #4
348	  Right #3
349	  Common #2
350	  Common #1
351	EOF
352'
353
354test_expect_success 'shortlog for two branches' '
355	test_config merge.log true &&
356	test_unconfig merge.summary &&
357	git checkout main &&
358	test_tick &&
359	git fetch . left right &&
360	git fmt-merge-msg <.git/FETCH_HEAD >actual1 &&
361
362	test_unconfig merge.log &&
363	test_config merge.summary true &&
364	git checkout main &&
365	test_tick &&
366	git fetch . left right &&
367	git fmt-merge-msg <.git/FETCH_HEAD >actual2 &&
368
369	test_config merge.log yes &&
370	test_unconfig merge.summary &&
371	git checkout main &&
372	test_tick &&
373	git fetch . left right &&
374	git fmt-merge-msg <.git/FETCH_HEAD >actual3 &&
375
376	test_unconfig merge.log &&
377	test_config merge.summary yes &&
378	git checkout main &&
379	test_tick &&
380	git fetch . left right &&
381	git fmt-merge-msg <.git/FETCH_HEAD >actual4 &&
382
383	test_cmp expected actual1 &&
384	test_cmp expected actual2 &&
385	test_cmp expected actual3 &&
386	test_cmp expected actual4
387'
388
389test_expect_success 'merge-msg -F' '
390	test_unconfig merge.log &&
391	test_config merge.summary yes &&
392	git checkout main &&
393	test_tick &&
394	git fetch . left right &&
395	git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
396	test_cmp expected actual
397'
398
399test_expect_success 'merge-msg -F in subdirectory' '
400	test_unconfig merge.log &&
401	test_config merge.summary yes &&
402	git checkout main &&
403	test_tick &&
404	git fetch . left right &&
405	mkdir sub &&
406	cp .git/FETCH_HEAD sub/FETCH_HEAD &&
407	(
408		cd sub &&
409		git fmt-merge-msg -F FETCH_HEAD >../actual
410	) &&
411	test_cmp expected actual
412'
413
414test_expect_success 'merge-msg with nothing to merge' '
415	test_unconfig merge.log &&
416	test_config merge.summary yes &&
417
418	(
419		cd remote &&
420		git checkout -b unrelated &&
421		test_tick &&
422		git fetch origin &&
423		git fmt-merge-msg <.git/FETCH_HEAD >../actual
424	) &&
425
426	test_must_be_empty actual
427'
428
429test_expect_success 'merge-msg tag' '
430	cat >expected <<-EOF &&
431	Merge tag ${apos}tag-r3${apos}
432
433	* tag ${apos}tag-r3${apos}:
434	  Right #3
435	  Common #2
436	  Common #1
437	EOF
438
439	test_unconfig merge.log &&
440	test_config merge.summary yes &&
441
442	git checkout main &&
443	test_tick &&
444	git fetch . tag tag-r3 &&
445
446	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
447	test_cmp expected actual
448'
449
450test_expect_success 'merge-msg two tags' '
451	cat >expected <<-EOF &&
452	Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos}
453
454	* tag ${apos}tag-r3${apos}:
455	  Right #3
456	  Common #2
457	  Common #1
458
459	# By Another Author (3) and A U Thor (2)
460	# Via Another Committer
461	* tag ${apos}tag-l5${apos}:
462	  Left #5
463	  Left #4
464	  Left #3
465	  Common #2
466	  Common #1
467	EOF
468
469	test_unconfig merge.log &&
470	test_config merge.summary yes &&
471
472	git checkout main &&
473	test_tick &&
474	git fetch . tag tag-r3 tag tag-l5 &&
475
476	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
477	test_cmp expected actual
478'
479
480test_expect_success 'merge-msg tag and branch' '
481	cat >expected <<-EOF &&
482	Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos}
483
484	* tag ${apos}tag-r3${apos}:
485	  Right #3
486	  Common #2
487	  Common #1
488
489	# By Another Author (3) and A U Thor (2)
490	# Via Another Committer
491	* left:
492	  Left #5
493	  Left #4
494	  Left #3
495	  Common #2
496	  Common #1
497	EOF
498
499	test_unconfig merge.log &&
500	test_config merge.summary yes &&
501
502	git checkout main &&
503	test_tick &&
504	git fetch . tag tag-r3 left &&
505
506	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
507	test_cmp expected actual
508'
509
510test_expect_success 'merge-msg lots of commits' '
511	{
512		cat <<-EOF &&
513		Merge branch ${apos}long${apos}
514
515		* long: (35 commits)
516		EOF
517
518		i=29 &&
519		while test $i -gt 9
520		do
521			echo "  $i" &&
522			i=$(($i-1))
523		done &&
524		echo "  ..."
525	} >expected &&
526
527	test_config merge.summary yes &&
528
529	git checkout main &&
530	test_tick &&
531	git fetch . long &&
532
533	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
534	test_cmp expected actual
535'
536
537test_expect_success 'merge-msg with "merging" an annotated tag' '
538	test_config merge.log true &&
539
540	git checkout main^0 &&
541	git commit --allow-empty -m "One step ahead" &&
542	git tag -a -m "An annotated one" annote HEAD &&
543
544	git checkout main &&
545	git fetch . annote &&
546
547	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
548	{
549		cat <<-\EOF
550		Merge tag '\''annote'\''
551
552		An annotated one
553
554		* tag '\''annote'\'':
555		  One step ahead
556		EOF
557	} >expected &&
558	test_cmp expected actual &&
559
560	test_when_finished "git reset --hard" &&
561	annote=$(git rev-parse annote) &&
562	git merge --no-commit --no-ff $annote &&
563	{
564		cat <<-EOF
565		Merge tag '\''$annote'\''
566
567		An annotated one
568
569		* tag '\''$annote'\'':
570		  One step ahead
571		EOF
572	} >expected &&
573	test_cmp expected .git/MERGE_MSG
574'
575
576test_expect_success 'merge.suppressDest configuration' '
577	git checkout -B side main &&
578	git commit --allow-empty -m "One step ahead" &&
579	git checkout main &&
580	git fetch . side &&
581
582	git -c merge.suppressDest="" fmt-merge-msg <.git/FETCH_HEAD >full.1 &&
583	head -n1 full.1 >actual &&
584	grep -e "Merge branch .side. into main" actual &&
585
586	git -c merge.suppressDest="mast" fmt-merge-msg <.git/FETCH_HEAD >full.2 &&
587	head -n1 full.2 >actual &&
588	grep -e "Merge branch .side. into main$" actual &&
589
590	git -c merge.suppressDest="ma?*[rn]" fmt-merge-msg <.git/FETCH_HEAD >full.3 &&
591	head -n1 full.3 >actual &&
592	grep -e "Merge branch .side." actual &&
593	! grep -e " into main$" actual
594'
595
596test_done
597