3 # Copyright (c) 2006, Junio C Hamano
6 test_description
='fmt-merge-msg test'
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12 .
"$TEST_DIRECTORY/lib-gpg.sh"
14 test_expect_success setup
'
18 git commit -m "Initial" &&
26 git commit -a -m "Second" &&
28 git checkout -b left &&
32 git commit -a -m "Common #1" &&
36 git commit -a -m "Common #2" &&
42 GIT_COMMITTER_NAME="Another Committer" \
43 GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #3" &&
47 GIT_COMMITTER_NAME="Another Committer" \
48 GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #4" &&
52 GIT_COMMITTER_NAME="Another Committer" \
53 GIT_AUTHOR_NAME="Another Author" git commit -a -m "Left #5" &&
61 git commit -a -m "Right #3" &&
66 git commit -a -m "Right #4" &&
70 git commit -a -m "Right #5" &&
72 git checkout -b long &&
73 test_commit_bulk --start=0 --message=%s --filename=one 30 &&
80 test_expect_success GPG
'set up a signed tag' '
81 git tag -s -m signed-tag-msg signed-good-tag left
84 test_expect_success GPGSSH
'created ssh signed commit and tag' '
85 test_config gpg.format ssh &&
86 git checkout -b signed-ssh &&
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
94 test_expect_success GPGSSH
,GPGSSH_VERIFYTIME
'create signed tags with keys having defined lifetimes' '
95 test_when_finished "test_unconfig commit.gpgsign" &&
96 test_config gpg.format ssh &&
97 git checkout -b signed-expiry-ssh &&
101 echo expired >file && test_tick && git commit -a -m expired -S"${GPGSSH_KEY_EXPIRED}" &&
102 git tag -s -u "${GPGSSH_KEY_EXPIRED}" -m expired-signed expired-signed &&
104 echo notyetvalid >file && test_tick && git commit -a -m notyetvalid -S"${GPGSSH_KEY_NOTYETVALID}" &&
105 git tag -s -u "${GPGSSH_KEY_NOTYETVALID}" -m notyetvalid-signed notyetvalid-signed &&
107 echo timeboxedvalid >file && test_tick && git commit -a -m timeboxedvalid -S"${GPGSSH_KEY_TIMEBOXEDVALID}" &&
108 git tag -s -u "${GPGSSH_KEY_TIMEBOXEDVALID}" -m timeboxedvalid-signed timeboxedvalid-signed &&
110 echo timeboxedinvalid >file && test_tick && git commit -a -m timeboxedinvalid -S"${GPGSSH_KEY_TIMEBOXEDINVALID}" &&
111 git tag -s -u "${GPGSSH_KEY_TIMEBOXEDINVALID}" -m timeboxedinvalid-signed timeboxedinvalid-signed
114 test_expect_success
'message for merging local branch' '
115 echo "Merge branch ${apos}left${apos}" >expected &&
120 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
121 test_cmp expected actual
124 test_expect_success GPG
'message for merging local tag signed by good key' '
126 git fetch . signed-good-tag &&
127 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
128 grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
129 grep "^signed-tag-msg" actual &&
130 grep "^# gpg: Signature made" actual &&
131 grep "^# gpg: Good signature from" actual
134 test_expect_success GPG
'message for merging local tag signed by unknown key' '
136 git fetch . signed-good-tag &&
137 GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual &&
138 grep "^Merge tag ${apos}signed-good-tag${apos}" actual &&
139 grep "^signed-tag-msg" actual &&
140 grep "^# gpg: Signature made" actual &&
141 grep -E "^# gpg: Can${apos}t check signature: (public key not found|No public key)" actual
144 test_expect_success GPGSSH
'message for merging local tag signed by good ssh key' '
145 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
147 git fetch . signed-good-ssh-tag &&
148 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
149 grep "^Merge tag ${apos}signed-good-ssh-tag${apos}" actual &&
150 grep "^signed-ssh-tag-msg" actual &&
151 grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual &&
152 ! grep "${GPGSSH_BAD_SIGNATURE}" actual
155 test_expect_success GPGSSH
'message for merging local tag signed by unknown ssh key' '
156 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
158 git fetch . signed-untrusted-ssh-tag &&
159 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
160 grep "^Merge tag ${apos}signed-untrusted-ssh-tag${apos}" actual &&
161 grep "^signed-ssh-tag-msg-untrusted" actual &&
162 grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual &&
163 ! grep "${GPGSSH_BAD_SIGNATURE}" actual &&
164 grep "${GPGSSH_KEY_NOT_TRUSTED}" actual
167 test_expect_success GPGSSH
,GPGSSH_VERIFYTIME
'message for merging local tag signed by expired ssh key' '
168 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
170 git fetch . expired-signed &&
171 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
172 grep "^Merge tag ${apos}expired-signed${apos}" actual &&
173 grep "^expired-signed" actual &&
174 ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual
177 test_expect_success GPGSSH
,GPGSSH_VERIFYTIME
'message for merging local tag signed by not yet valid ssh key' '
178 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
180 git fetch . notyetvalid-signed &&
181 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
182 grep "^Merge tag ${apos}notyetvalid-signed${apos}" actual &&
183 grep "^notyetvalid-signed" actual &&
184 ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual
187 test_expect_success GPGSSH
,GPGSSH_VERIFYTIME
'message for merging local tag signed by valid timeboxed ssh key' '
188 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
190 git fetch . timeboxedvalid-signed &&
191 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
192 grep "^Merge tag ${apos}timeboxedvalid-signed${apos}" actual &&
193 grep "^timeboxedvalid-signed" actual &&
194 grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual &&
195 ! grep "${GPGSSH_BAD_SIGNATURE}" actual
198 test_expect_success GPGSSH
,GPGSSH_VERIFYTIME
'message for merging local tag signed by invalid timeboxed ssh key' '
199 test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
201 git fetch . timeboxedinvalid-signed &&
202 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
203 grep "^Merge tag ${apos}timeboxedinvalid-signed${apos}" actual &&
204 grep "^timeboxedinvalid-signed" actual &&
205 ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual
208 test_expect_success
'message for merging external branch' '
209 echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
212 git fetch "$(pwd)" left &&
214 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
215 test_cmp expected actual
218 test_expect_success
'[merge] summary/log configuration' '
219 cat >expected <<-EOF &&
220 Merge branch ${apos}left${apos}
222 # By Another Author (3) and A U Thor (2)
223 # Via Another Committer
232 test_config merge.log true &&
233 test_unconfig merge.summary &&
239 git fmt-merge-msg <.git/FETCH_HEAD >actual1 &&
241 test_unconfig merge.log &&
242 test_config merge.summary true &&
248 git fmt-merge-msg <.git/FETCH_HEAD >actual2 &&
250 test_cmp expected actual1 &&
251 test_cmp expected actual2
254 test_expect_success
'setup FETCH_HEAD' '
260 test_expect_success
'merge.log=3 limits shortlog length' '
261 cat >expected <<-EOF &&
262 Merge branch ${apos}left${apos}
264 # By Another Author (3) and A U Thor (2)
265 # Via Another Committer
273 git -c merge.log=3 fmt-merge-msg <.git/FETCH_HEAD >actual &&
274 test_cmp expected actual
277 test_expect_success
'merge.log=5 shows all 5 commits' '
278 cat >expected <<-EOF &&
279 Merge branch ${apos}left${apos}
281 # By Another Author (3) and A U Thor (2)
282 # Via Another Committer
291 git -c merge.log=5 fmt-merge-msg <.git/FETCH_HEAD >actual &&
292 test_cmp expected actual
295 test_expect_success
'--log=5 with custom comment character' '
296 cat >expected <<-EOF &&
297 Merge branch ${apos}left${apos}
299 x By Another Author (3) and A U Thor (2)
300 x Via Another Committer
309 git -c core.commentchar="x" fmt-merge-msg --log=5 <.git/FETCH_HEAD >actual &&
310 test_cmp expected actual
313 test_expect_success
'merge.log=0 disables shortlog' '
314 echo "Merge branch ${apos}left${apos}" >expected &&
315 git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual &&
316 test_cmp expected actual
319 test_expect_success
'--log=3 limits shortlog length' '
320 cat >expected <<-EOF &&
321 Merge branch ${apos}left${apos}
323 # By Another Author (3) and A U Thor (2)
324 # Via Another Committer
332 git fmt-merge-msg --log=3 <.git/FETCH_HEAD >actual &&
333 test_cmp expected actual
336 test_expect_success
'--log=5 shows all 5 commits' '
337 cat >expected <<-EOF &&
338 Merge branch ${apos}left${apos}
340 # By Another Author (3) and A U Thor (2)
341 # Via Another Committer
350 git fmt-merge-msg --log=5 <.git/FETCH_HEAD >actual &&
351 test_cmp expected actual
354 test_expect_success
'--no-log disables shortlog' '
355 echo "Merge branch ${apos}left${apos}" >expected &&
356 git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
357 test_cmp expected actual
360 test_expect_success
'--log=0 disables shortlog' '
361 echo "Merge branch ${apos}left${apos}" >expected &&
362 git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
363 test_cmp expected actual
366 test_expect_success
'fmt-merge-msg -m' '
367 echo "Sync with left" >expected &&
368 cat >expected.log <<-EOF &&
371 # By Another Author (3) and A U Thor (2)
372 # Via Another Committer
373 * ${apos}left${apos} of $(pwd):
381 test_unconfig merge.log &&
382 test_unconfig merge.summary &&
384 git fetch "$(pwd)" left &&
385 git fmt-merge-msg -m "Sync with left" <.git/FETCH_HEAD >actual &&
386 git fmt-merge-msg --log -m "Sync with left" \
387 <.git/FETCH_HEAD >actual.log &&
388 test_config merge.log true &&
389 git fmt-merge-msg -m "Sync with left" \
390 <.git/FETCH_HEAD >actual.log-config &&
391 git fmt-merge-msg --no-log -m "Sync with left" \
392 <.git/FETCH_HEAD >actual.nolog &&
394 test_cmp expected actual &&
395 test_cmp expected.log actual.log &&
396 test_cmp expected.log actual.log-config &&
397 test_cmp expected actual.nolog
400 test_expect_success
'setup: expected shortlog for two branches' '
402 Merge branches ${apos}left${apos} and ${apos}right${apos}
404 # By Another Author (3) and A U Thor (2)
405 # Via Another Committer
422 test_expect_success
'shortlog for two branches' '
423 test_config merge.log true &&
424 test_unconfig merge.summary &&
427 git fetch . left right &&
428 git fmt-merge-msg <.git/FETCH_HEAD >actual1 &&
430 test_unconfig merge.log &&
431 test_config merge.summary true &&
434 git fetch . left right &&
435 git fmt-merge-msg <.git/FETCH_HEAD >actual2 &&
437 test_config merge.log yes &&
438 test_unconfig merge.summary &&
441 git fetch . left right &&
442 git fmt-merge-msg <.git/FETCH_HEAD >actual3 &&
444 test_unconfig merge.log &&
445 test_config merge.summary yes &&
448 git fetch . left right &&
449 git fmt-merge-msg <.git/FETCH_HEAD >actual4 &&
451 test_cmp expected actual1 &&
452 test_cmp expected actual2 &&
453 test_cmp expected actual3 &&
454 test_cmp expected actual4
457 test_expect_success
'merge-msg -F' '
458 test_unconfig merge.log &&
459 test_config merge.summary yes &&
462 git fetch . left right &&
463 git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
464 test_cmp expected actual
467 test_expect_success
'merge-msg -F in subdirectory' '
468 test_unconfig merge.log &&
469 test_config merge.summary yes &&
472 git fetch . left right &&
474 cp .git/FETCH_HEAD sub/FETCH_HEAD &&
477 git fmt-merge-msg -F FETCH_HEAD >../actual
479 test_cmp expected actual
482 test_expect_success
'merge-msg with nothing to merge' '
483 test_unconfig merge.log &&
484 test_config merge.summary yes &&
488 git checkout -b unrelated &&
491 git fmt-merge-msg <.git/FETCH_HEAD >../actual
494 test_must_be_empty actual
497 test_expect_success
'merge-msg tag' '
498 cat >expected <<-EOF &&
499 Merge tag ${apos}tag-r3${apos}
501 * tag ${apos}tag-r3${apos}:
507 test_unconfig merge.log &&
508 test_config merge.summary yes &&
512 git fetch . tag tag-r3 &&
514 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
515 test_cmp expected actual
518 test_expect_success
'merge-msg two tags' '
519 cat >expected <<-EOF &&
520 Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos}
522 * tag ${apos}tag-r3${apos}:
527 # By Another Author (3) and A U Thor (2)
528 # Via Another Committer
529 * tag ${apos}tag-l5${apos}:
537 test_unconfig merge.log &&
538 test_config merge.summary yes &&
542 git fetch . tag tag-r3 tag tag-l5 &&
544 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
545 test_cmp expected actual
548 test_expect_success
'merge-msg tag and branch' '
549 cat >expected <<-EOF &&
550 Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos}
552 * tag ${apos}tag-r3${apos}:
557 # By Another Author (3) and A U Thor (2)
558 # Via Another Committer
567 test_unconfig merge.log &&
568 test_config merge.summary yes &&
572 git fetch . tag tag-r3 left &&
574 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
575 test_cmp expected actual
578 test_expect_success
'merge-msg lots of commits' '
581 Merge branch ${apos}long${apos}
590 i=$(($i-1)) || return 1
595 test_config merge.summary yes &&
601 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
602 test_cmp expected actual
605 test_expect_success
'merge-msg with "merging" an annotated tag' '
606 test_config merge.log true &&
608 git checkout main^0 &&
609 git commit --allow-empty -m "One step ahead" &&
610 git tag -a -m "An annotated one" annote HEAD &&
613 git fetch . annote &&
615 git fmt-merge-msg <.git/FETCH_HEAD >actual &&
618 Merge tag '\''annote'\''
622 * tag '\''annote'\'':
626 test_cmp expected actual &&
628 test_when_finished "git reset --hard" &&
629 annote=$(git rev-parse annote) &&
630 git merge --no-commit --no-ff $annote &&
633 Merge tag '\''$annote'\''
637 * tag '\''$annote'\'':
641 test_cmp expected .git/MERGE_MSG
644 test_expect_success
'merge --into-name=<name>' '
645 test_when_finished "git checkout main" &&
646 git checkout -B side main &&
647 git commit --allow-empty -m "One step ahead" &&
649 git checkout --detach main &&
650 git merge --no-ff side &&
651 git show -s --format="%s" >full.0 &&
652 head -n1 full.0 >actual &&
653 # expect that HEAD is shown as-is
654 grep -e "Merge branch .side. into HEAD$" actual &&
656 git reset --hard main &&
657 git merge --no-ff --into-name=main side &&
658 git show -s --format="%s" >full.1 &&
659 head -n1 full.1 >actual &&
660 # expect that we pretend to be merging to main, that is suppressed
661 grep -e "Merge branch .side.$" actual &&
663 git checkout -b throwaway main &&
664 git merge --no-ff --into-name=main side &&
665 git show -s --format="%s" >full.2 &&
666 head -n1 full.2 >actual &&
667 # expect that we pretend to be merging to main, that is suppressed
668 grep -e "Merge branch .side.$" actual
671 test_expect_success
'merge.suppressDest configuration' '
672 test_when_finished "git checkout main" &&
673 git checkout -B side main &&
674 git commit --allow-empty -m "One step ahead" &&
678 git -c merge.suppressDest="" fmt-merge-msg <.git/FETCH_HEAD >full.1 &&
679 head -n1 full.1 >actual &&
680 grep -e "Merge branch .side. into main" actual &&
682 git -c merge.suppressDest="mast" fmt-merge-msg <.git/FETCH_HEAD >full.2 &&
683 head -n1 full.2 >actual &&
684 grep -e "Merge branch .side. into main$" actual &&
686 git -c merge.suppressDest="ma?*[rn]" fmt-merge-msg <.git/FETCH_HEAD >full.3 &&
687 head -n1 full.3 >actual &&
688 grep -e "Merge branch .side." actual &&
689 ! grep -e " into main$" actual &&
691 git checkout --detach HEAD &&
692 git -c merge.suppressDest="main" fmt-merge-msg <.git/FETCH_HEAD >full.4 &&
693 head -n1 full.4 >actual &&
694 grep -e "Merge branch .side. into HEAD$" actual &&
696 git -c merge.suppressDest="main" fmt-merge-msg \
697 --into-name=main <.git/FETCH_HEAD >full.5 &&
698 head -n1 full.5 >actual &&
699 grep -e "Merge branch .side." actual &&
700 ! grep -e " into main$" actual &&
701 ! grep -e " into HEAD$" actual