dir: report number of visited directories and paths with trace2
[git] / t / t7600-merge.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Lars Hjemli
4 #
5
6 test_description='git merge
7
8 Testing basic merge operations/option parsing.
9
10 ! [c0] commit 0
11  ! [c1] commit 1
12   ! [c2] commit 2
13    ! [c3] commit 3
14     ! [c4] c4
15      ! [c5] c5
16       ! [c6] c6
17        * [main] Merge commit 'c1'
18 --------
19        - [main] Merge commit 'c1'
20  +     * [c1] commit 1
21       +  [c6] c6
22      +   [c5] c5
23     ++   [c4] c4
24    ++++  [c3] commit 3
25   +      [c2] commit 2
26 +++++++* [c0] commit 0
27 '
28
29 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
30 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
31
32 . ./test-lib.sh
33 . "$TEST_DIRECTORY"/lib-gpg.sh
34
35 test_write_lines 1 2 3 4 5 6 7 8 9 >file
36 cp file file.orig
37 test_write_lines '1 X' 2 3 4 5 6 7 8 9 >file.1
38 test_write_lines 1 2 '3 X' 4 5 6 7 8 9 >file.3
39 test_write_lines 1 2 3 4 '5 X' 6 7 8 9 >file.5
40 test_write_lines 1 2 3 4 5 6 7 8 '9 X' >file.9
41 test_write_lines 1 2 3 4 5 6 7 8 '9 Y' >file.9y
42 test_write_lines '1 X' 2 3 4 5 6 7 8 9 >result.1
43 test_write_lines '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
44 test_write_lines '1 X' 2 3 4 5 6 7 8 '9 X' >result.1-9
45 test_write_lines '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
46 test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9
47 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z
48
49 create_merge_msgs () {
50         echo "Merge tag 'c2'" >msg.1-5 &&
51         echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 &&
52         {
53                 echo "Squashed commit of the following:" &&
54                 echo &&
55                 git log --no-merges ^HEAD c1
56         } >squash.1 &&
57         {
58                 echo "Squashed commit of the following:" &&
59                 echo &&
60                 git log --no-merges ^HEAD c2
61         } >squash.1-5 &&
62         {
63                 echo "Squashed commit of the following:" &&
64                 echo &&
65                 git log --no-merges ^HEAD c2 c3
66         } >squash.1-5-9 &&
67         {
68                 echo "* tag 'c3':" &&
69                 echo "  commit 3"
70         } >msg.log
71 }
72
73 verify_merge () {
74         test_cmp "$2" "$1" &&
75         git update-index --refresh &&
76         git diff --exit-code &&
77         if test -n "$3"
78         then
79                 git show -s --pretty=tformat:%s HEAD >msg.act &&
80                 test_cmp "$3" msg.act
81         fi
82 }
83
84 verify_head () {
85         echo "$1" >head.expected &&
86         git rev-parse HEAD >head.actual &&
87         test_cmp head.expected head.actual
88 }
89
90 verify_parents () {
91         test_write_lines "$@" >parents.expected &&
92         >parents.actual &&
93         i=1 &&
94         while test $i -le $#
95         do
96                 git rev-parse HEAD^$i >>parents.actual &&
97                 i=$(expr $i + 1) ||
98                 return 1
99         done &&
100         test_must_fail git rev-parse --verify "HEAD^$i" &&
101         test_cmp parents.expected parents.actual
102 }
103
104 verify_mergeheads () {
105         test_write_lines "$@" >mergehead.expected &&
106         while read sha1 rest
107         do
108                 git rev-parse $sha1
109         done <.git/MERGE_HEAD >mergehead.actual &&
110         test_cmp mergehead.expected mergehead.actual
111 }
112
113 verify_no_mergehead () {
114         ! test -e .git/MERGE_HEAD
115 }
116
117 test_expect_success 'setup' '
118         git add file &&
119         test_tick &&
120         git commit -m "commit 0" &&
121         git tag c0 &&
122         c0=$(git rev-parse HEAD) &&
123         cp file.1 file &&
124         git add file &&
125         test_tick &&
126         git commit -m "commit 1" &&
127         git tag c1 &&
128         c1=$(git rev-parse HEAD) &&
129         git reset --hard "$c0" &&
130         cp file.5 file &&
131         git add file &&
132         test_tick &&
133         git commit -m "commit 2" &&
134         git tag c2 &&
135         c2=$(git rev-parse HEAD) &&
136         git reset --hard "$c0" &&
137         cp file.9y file &&
138         git add file &&
139         test_tick &&
140         git commit -m "commit 7" &&
141         git tag c7 &&
142         git reset --hard "$c0" &&
143         cp file.9 file &&
144         git add file &&
145         test_tick &&
146         git commit -m "commit 3" &&
147         git tag c3 &&
148         c3=$(git rev-parse HEAD) &&
149         git reset --hard "$c0" &&
150         create_merge_msgs
151 '
152
153 test_debug 'git log --graph --decorate --oneline --all'
154
155 test_expect_success 'test option parsing' '
156         test_must_fail git merge -$ c1 &&
157         test_must_fail git merge --no-such c1 &&
158         test_must_fail git merge -s foobar c1 &&
159         test_must_fail git merge -s=foobar c1 &&
160         test_must_fail git merge -m &&
161         test_must_fail git merge --abort foobar &&
162         test_must_fail git merge --abort --quiet &&
163         test_must_fail git merge --continue foobar &&
164         test_must_fail git merge --continue --quiet &&
165         test_must_fail git merge
166 '
167
168 test_expect_success 'merge -h with invalid index' '
169         mkdir broken &&
170         (
171                 cd broken &&
172                 git init &&
173                 >.git/index &&
174                 test_expect_code 129 git merge -h 2>usage
175         ) &&
176         test_i18ngrep "[Uu]sage: git merge" broken/usage
177 '
178
179 test_expect_success 'reject non-strategy with a git-merge-foo name' '
180         test_must_fail git merge -s index c1
181 '
182
183 test_expect_success 'merge c0 with c1' '
184         echo "OBJID HEAD@{0}: merge c1: Fast-forward" >reflog.expected &&
185
186         git reset --hard c0 &&
187         git merge c1 &&
188         verify_merge file result.1 &&
189         verify_head "$c1" &&
190
191         git reflog -1 >reflog.actual &&
192         sed "s/$_x05[0-9a-f]*/OBJID/g" reflog.actual >reflog.fuzzy &&
193         test_cmp reflog.expected reflog.fuzzy
194 '
195
196 test_debug 'git log --graph --decorate --oneline --all'
197
198 test_expect_success 'merge c0 with c1 with --ff-only' '
199         git reset --hard c0 &&
200         git merge --ff-only c1 &&
201         git merge --ff-only HEAD c0 c1 &&
202         verify_merge file result.1 &&
203         verify_head "$c1"
204 '
205
206 test_debug 'git log --graph --decorate --oneline --all'
207
208 test_expect_success 'merge from unborn branch' '
209         git checkout -f main &&
210         test_might_fail git branch -D kid &&
211
212         echo "OBJID HEAD@{0}: initial pull" >reflog.expected &&
213
214         git checkout --orphan kid &&
215         test_when_finished "git checkout -f main" &&
216         git rm -fr . &&
217         test_tick &&
218         git merge --ff-only c1 &&
219         verify_merge file result.1 &&
220         verify_head "$c1" &&
221
222         git reflog -1 >reflog.actual &&
223         sed "s/$_x05[0-9a-f][0-9a-f]/OBJID/g" reflog.actual >reflog.fuzzy &&
224         test_cmp reflog.expected reflog.fuzzy
225 '
226
227 test_debug 'git log --graph --decorate --oneline --all'
228
229 test_expect_success 'merge c1 with c2' '
230         git reset --hard c1 &&
231         test_tick &&
232         git merge c2 &&
233         verify_merge file result.1-5 msg.1-5 &&
234         verify_parents $c1 $c2
235 '
236
237 test_expect_success 'merge --squash c3 with c7' '
238         git reset --hard c3 &&
239         test_must_fail git merge --squash c7 &&
240         cat result.9z >file &&
241         git commit --no-edit -a &&
242
243         cat >expect <<-EOF &&
244         Squashed commit of the following:
245
246         $(git show -s c7)
247
248         # Conflicts:
249         #       file
250         EOF
251         git cat-file commit HEAD >raw &&
252         sed -e "1,/^$/d" raw >actual &&
253         test_cmp expect actual
254 '
255
256 test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
257         git config commit.cleanup scissors &&
258         git reset --hard c3 &&
259         test_must_fail git merge c7 &&
260         cat result.9z >file &&
261         git commit --no-edit -a &&
262
263         cat >expect <<-\EOF &&
264         Merge tag '"'"'c7'"'"'
265
266         # ------------------------ >8 ------------------------
267         # Do not modify or remove the line above.
268         # Everything below it will be ignored.
269         #
270         # Conflicts:
271         #       file
272         EOF
273         git cat-file commit HEAD >raw &&
274         sed -e "1,/^$/d" raw >actual &&
275         test_cmp expect actual
276 '
277
278 test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '
279         git config commit.cleanup scissors &&
280         git reset --hard c3 &&
281         test_must_fail git merge --squash c7 &&
282         cat result.9z >file &&
283         git commit --no-edit -a &&
284
285         cat >expect <<-EOF &&
286         Squashed commit of the following:
287
288         $(git show -s c7)
289
290         # ------------------------ >8 ------------------------
291         # Do not modify or remove the line above.
292         # Everything below it will be ignored.
293         #
294         # Conflicts:
295         #       file
296         EOF
297         git cat-file commit HEAD >raw &&
298         sed -e "1,/^$/d" raw >actual &&
299         test_cmp expect actual
300 '
301
302 test_debug 'git log --graph --decorate --oneline --all'
303
304 test_expect_success 'merge c1 with c2 and c3' '
305         git reset --hard c1 &&
306         test_tick &&
307         git merge c2 c3 &&
308         verify_merge file result.1-5-9 msg.1-5-9 &&
309         verify_parents $c1 $c2 $c3
310 '
311
312 test_debug 'git log --graph --decorate --oneline --all'
313
314 test_expect_success 'merges with --ff-only' '
315         git reset --hard c1 &&
316         test_tick &&
317         test_must_fail git merge --ff-only c2 &&
318         test_must_fail git merge --ff-only c3 &&
319         test_must_fail git merge --ff-only c2 c3 &&
320         git reset --hard c0 &&
321         git merge c3 &&
322         verify_head $c3
323 '
324
325 test_expect_success 'merges with merge.ff=only' '
326         git reset --hard c1 &&
327         test_tick &&
328         test_config merge.ff "only" &&
329         test_must_fail git merge c2 &&
330         test_must_fail git merge c3 &&
331         test_must_fail git merge c2 c3 &&
332         git reset --hard c0 &&
333         git merge c3 &&
334         verify_head $c3
335 '
336
337 test_expect_success 'merge c0 with c1 (no-commit)' '
338         git reset --hard c0 &&
339         git merge --no-commit c1 &&
340         verify_merge file result.1 &&
341         verify_head $c1
342 '
343
344 test_debug 'git log --graph --decorate --oneline --all'
345
346 test_expect_success 'merge c1 with c2 (no-commit)' '
347         git reset --hard c1 &&
348         git merge --no-commit c2 &&
349         verify_merge file result.1-5 &&
350         verify_head $c1 &&
351         verify_mergeheads $c2
352 '
353
354 test_debug 'git log --graph --decorate --oneline --all'
355
356 test_expect_success 'merge c1 with c2 and c3 (no-commit)' '
357         git reset --hard c1 &&
358         git merge --no-commit c2 c3 &&
359         verify_merge file result.1-5-9 &&
360         verify_head $c1 &&
361         verify_mergeheads $c2 $c3
362 '
363
364 test_debug 'git log --graph --decorate --oneline --all'
365
366 test_expect_success 'merge c0 with c1 (squash)' '
367         git reset --hard c0 &&
368         git merge --squash c1 &&
369         verify_merge file result.1 &&
370         verify_head $c0 &&
371         verify_no_mergehead &&
372         test_cmp squash.1 .git/SQUASH_MSG
373 '
374
375 test_debug 'git log --graph --decorate --oneline --all'
376
377 test_expect_success 'merge c0 with c1 (squash, ff-only)' '
378         git reset --hard c0 &&
379         git merge --squash --ff-only c1 &&
380         verify_merge file result.1 &&
381         verify_head $c0 &&
382         verify_no_mergehead &&
383         test_cmp squash.1 .git/SQUASH_MSG
384 '
385
386 test_debug 'git log --graph --decorate --oneline --all'
387
388 test_expect_success 'merge c1 with c2 (squash)' '
389         git reset --hard c1 &&
390         git merge --squash c2 &&
391         verify_merge file result.1-5 &&
392         verify_head $c1 &&
393         verify_no_mergehead &&
394         test_cmp squash.1-5 .git/SQUASH_MSG
395 '
396
397 test_debug 'git log --graph --decorate --oneline --all'
398
399 test_expect_success 'unsuccessful merge of c1 with c2 (squash, ff-only)' '
400         git reset --hard c1 &&
401         test_must_fail git merge --squash --ff-only c2
402 '
403
404 test_debug 'git log --graph --decorate --oneline --all'
405
406 test_expect_success 'merge c1 with c2 and c3 (squash)' '
407         git reset --hard c1 &&
408         git merge --squash c2 c3 &&
409         verify_merge file result.1-5-9 &&
410         verify_head $c1 &&
411         verify_no_mergehead &&
412         test_cmp squash.1-5-9 .git/SQUASH_MSG
413 '
414
415 test_debug 'git log --graph --decorate --oneline --all'
416
417 test_expect_success 'merge c1 with c2 (no-commit in config)' '
418         git reset --hard c1 &&
419         test_config branch.main.mergeoptions "--no-commit" &&
420         git merge c2 &&
421         verify_merge file result.1-5 &&
422         verify_head $c1 &&
423         verify_mergeheads $c2
424 '
425
426 test_debug 'git log --graph --decorate --oneline --all'
427
428 test_expect_success 'merge c1 with c2 (log in config)' '
429         git reset --hard c1 &&
430         git merge --log c2 &&
431         git show -s --pretty=tformat:%s%n%b >expect &&
432
433         test_config branch.main.mergeoptions "--log" &&
434         git reset --hard c1 &&
435         git merge c2 &&
436         git show -s --pretty=tformat:%s%n%b >actual &&
437
438         test_cmp expect actual
439 '
440
441 test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
442         git reset --hard c1 &&
443         git merge c2 &&
444         git show -s --pretty=tformat:%s%n%b >expect &&
445
446         test_config branch.main.mergeoptions "--no-log" &&
447         test_config merge.log "true" &&
448         git reset --hard c1 &&
449         git merge c2 &&
450         git show -s --pretty=tformat:%s%n%b >actual &&
451
452         test_cmp expect actual
453 '
454
455 test_expect_success 'merge c1 with c2 (squash in config)' '
456         git reset --hard c1 &&
457         test_config branch.main.mergeoptions "--squash" &&
458         git merge c2 &&
459         verify_merge file result.1-5 &&
460         verify_head $c1 &&
461         verify_no_mergehead &&
462         test_cmp squash.1-5 .git/SQUASH_MSG
463 '
464
465 test_debug 'git log --graph --decorate --oneline --all'
466
467 test_expect_success 'override config option -n with --summary' '
468         git reset --hard c1 &&
469         test_config branch.main.mergeoptions "-n" &&
470         test_tick &&
471         git merge --summary c2 >diffstat.txt &&
472         verify_merge file result.1-5 msg.1-5 &&
473         verify_parents $c1 $c2 &&
474         if ! grep "^ file |  *2 +-$" diffstat.txt
475         then
476                 echo "[OOPS] diffstat was not generated with --summary"
477                 false
478         fi
479 '
480
481 test_expect_success 'override config option -n with --stat' '
482         git reset --hard c1 &&
483         test_config branch.main.mergeoptions "-n" &&
484         test_tick &&
485         git merge --stat c2 >diffstat.txt &&
486         verify_merge file result.1-5 msg.1-5 &&
487         verify_parents $c1 $c2 &&
488         if ! grep "^ file |  *2 +-$" diffstat.txt
489         then
490                 echo "[OOPS] diffstat was not generated with --stat"
491                 false
492         fi
493 '
494
495 test_debug 'git log --graph --decorate --oneline --all'
496
497 test_expect_success 'override config option --stat' '
498         git reset --hard c1 &&
499         test_config branch.main.mergeoptions "--stat" &&
500         test_tick &&
501         git merge -n c2 >diffstat.txt &&
502         verify_merge file result.1-5 msg.1-5 &&
503         verify_parents $c1 $c2 &&
504         if grep "^ file |  *2 +-$" diffstat.txt
505         then
506                 echo "[OOPS] diffstat was generated"
507                 false
508         fi
509 '
510
511 test_debug 'git log --graph --decorate --oneline --all'
512
513 test_expect_success 'merge c1 with c2 (override --no-commit)' '
514         git reset --hard c1 &&
515         test_config branch.main.mergeoptions "--no-commit" &&
516         test_tick &&
517         git merge --commit c2 &&
518         verify_merge file result.1-5 msg.1-5 &&
519         verify_parents $c1 $c2
520 '
521
522 test_debug 'git log --graph --decorate --oneline --all'
523
524 test_expect_success 'merge c1 with c2 (override --squash)' '
525         git reset --hard c1 &&
526         test_config branch.main.mergeoptions "--squash" &&
527         test_tick &&
528         git merge --no-squash c2 &&
529         verify_merge file result.1-5 msg.1-5 &&
530         verify_parents $c1 $c2
531 '
532
533 test_debug 'git log --graph --decorate --oneline --all'
534
535 test_expect_success 'merge c0 with c1 (no-ff)' '
536         git reset --hard c0 &&
537         test_tick &&
538         git merge --no-ff c1 &&
539         verify_merge file result.1 &&
540         verify_parents $c0 $c1
541 '
542
543 test_debug 'git log --graph --decorate --oneline --all'
544
545 test_expect_success 'merge c0 with c1 (merge.ff=false)' '
546         git reset --hard c0 &&
547         test_config merge.ff "false" &&
548         test_tick &&
549         git merge c1 &&
550         verify_merge file result.1 &&
551         verify_parents $c0 $c1
552 '
553 test_debug 'git log --graph --decorate --oneline --all'
554
555 test_expect_success 'combine branch.main.mergeoptions with merge.ff' '
556         git reset --hard c0 &&
557         test_config branch.main.mergeoptions "--ff" &&
558         test_config merge.ff "false" &&
559         test_tick &&
560         git merge c1 &&
561         verify_merge file result.1 &&
562         verify_parents "$c0"
563 '
564
565 test_expect_success 'tolerate unknown values for merge.ff' '
566         git reset --hard c0 &&
567         test_config merge.ff "something-new" &&
568         test_tick &&
569         git merge c1 2>message &&
570         verify_head "$c1" &&
571         test_must_be_empty message
572 '
573
574 test_expect_success 'combining --squash and --no-ff is refused' '
575         git reset --hard c0 &&
576         test_must_fail git merge --squash --no-ff c1 &&
577         test_must_fail git merge --no-ff --squash c1
578 '
579
580 test_expect_success 'combining --squash and --commit is refused' '
581         git reset --hard c0 &&
582         test_must_fail git merge --squash --commit c1 &&
583         test_must_fail git merge --commit --squash c1
584 '
585
586 test_expect_success 'option --ff-only overwrites --no-ff' '
587         git merge --no-ff --ff-only c1 &&
588         test_must_fail git merge --no-ff --ff-only c2
589 '
590
591 test_expect_success 'option --no-ff overrides merge.ff=only config' '
592         git reset --hard c0 &&
593         test_config merge.ff only &&
594         git merge --no-ff c1
595 '
596
597 test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '
598         git reset --hard c0 &&
599         test_config branch.main.mergeoptions "--no-ff" &&
600         git merge --ff c1 &&
601         verify_merge file result.1 &&
602         verify_head $c1
603 '
604
605 test_expect_success 'merge log message' '
606         git reset --hard c0 &&
607         git merge --no-log c2 &&
608         git show -s --pretty=format:%b HEAD >msg.act &&
609         test_must_be_empty msg.act &&
610
611         git reset --hard c0 &&
612         test_config branch.main.mergeoptions "--no-ff" &&
613         git merge --no-log c2 &&
614         git show -s --pretty=format:%b HEAD >msg.act &&
615         test_must_be_empty msg.act &&
616
617         git merge --log c3 &&
618         git show -s --pretty=format:%b HEAD >msg.act &&
619         test_cmp msg.log msg.act &&
620
621         git reset --hard HEAD^ &&
622         test_config merge.log "yes" &&
623         git merge c3 &&
624         git show -s --pretty=format:%b HEAD >msg.act &&
625         test_cmp msg.log msg.act
626 '
627
628 test_debug 'git log --graph --decorate --oneline --all'
629
630 test_expect_success 'merge c1 with c0, c2, c0, and c1' '
631        git reset --hard c1 &&
632        test_tick &&
633        git merge c0 c2 c0 c1 &&
634        verify_merge file result.1-5 &&
635        verify_parents $c1 $c2
636 '
637
638 test_debug 'git log --graph --decorate --oneline --all'
639
640 test_expect_success 'merge c1 with c0, c2, c0, and c1' '
641        git reset --hard c1 &&
642        test_tick &&
643        git merge c0 c2 c0 c1 &&
644        verify_merge file result.1-5 &&
645        verify_parents $c1 $c2
646 '
647
648 test_debug 'git log --graph --decorate --oneline --all'
649
650 test_expect_success 'merge c1 with c1 and c2' '
651        git reset --hard c1 &&
652        test_tick &&
653        git merge c1 c2 &&
654        verify_merge file result.1-5 &&
655        verify_parents $c1 $c2
656 '
657
658 test_debug 'git log --graph --decorate --oneline --all'
659
660 test_expect_success 'merge fast-forward in a dirty tree' '
661        git reset --hard c0 &&
662        mv file file1 &&
663        cat file1 >file &&
664        rm -f file1 &&
665        git merge c2
666 '
667
668 test_debug 'git log --graph --decorate --oneline --all'
669
670 test_expect_success 'in-index merge' '
671         git reset --hard c0 &&
672         git merge --no-ff -s resolve c1 >out &&
673         test_i18ngrep "Wonderful." out &&
674         verify_parents $c0 $c1
675 '
676
677 test_debug 'git log --graph --decorate --oneline --all'
678
679 test_expect_success 'refresh the index before merging' '
680         git reset --hard c1 &&
681         cp file file.n && mv -f file.n file &&
682         git merge c3
683 '
684
685 test_expect_success 'merge with --autostash' '
686         git reset --hard c1 &&
687         git merge-file file file.orig file.9 &&
688         git merge --autostash c2 2>err &&
689         test_i18ngrep "Applied autostash." err &&
690         git show HEAD:file >merge-result &&
691         test_cmp result.1-5 merge-result &&
692         test_cmp result.1-5-9 file
693 '
694
695 test_expect_success 'merge with merge.autoStash' '
696         test_config merge.autoStash true &&
697         git reset --hard c1 &&
698         git merge-file file file.orig file.9 &&
699         git merge c2 2>err &&
700         test_i18ngrep "Applied autostash." err &&
701         git show HEAD:file >merge-result &&
702         test_cmp result.1-5 merge-result &&
703         test_cmp result.1-5-9 file
704 '
705
706 test_expect_success 'fast-forward merge with --autostash' '
707         git reset --hard c0 &&
708         git merge-file file file.orig file.5 &&
709         git merge --autostash c1 2>err &&
710         test_i18ngrep "Applied autostash." err &&
711         test_cmp result.1-5 file
712 '
713
714 test_expect_success 'octopus merge with --autostash' '
715         git reset --hard c1 &&
716         git merge-file file file.orig file.3 &&
717         git merge --autostash c2 c3 2>err &&
718         test_i18ngrep "Applied autostash." err &&
719         git show HEAD:file >merge-result &&
720         test_cmp result.1-5-9 merge-result &&
721         test_cmp result.1-3-5-9 file
722 '
723
724 test_expect_success 'conflicted merge with --autostash, --abort restores stash' '
725         git reset --hard c3 &&
726         cp file.1 file &&
727         test_must_fail git merge --autostash c7 &&
728         git merge --abort 2>err &&
729         test_i18ngrep "Applied autostash." err &&
730         test_cmp file.1 file
731 '
732
733 test_expect_success 'completed merge (git commit) with --no-commit and --autostash' '
734         git reset --hard c1 &&
735         git merge-file file file.orig file.9 &&
736         git diff >expect &&
737         git merge --no-commit --autostash c2 &&
738         git stash show -p MERGE_AUTOSTASH >actual &&
739         test_cmp expect actual &&
740         git commit 2>err &&
741         test_i18ngrep "Applied autostash." err &&
742         git show HEAD:file >merge-result &&
743         test_cmp result.1-5 merge-result &&
744         test_cmp result.1-5-9 file
745 '
746
747 test_expect_success 'completed merge (git merge --continue) with --no-commit and --autostash' '
748         git reset --hard c1 &&
749         git merge-file file file.orig file.9 &&
750         git diff >expect &&
751         git merge --no-commit --autostash c2 &&
752         git stash show -p MERGE_AUTOSTASH >actual &&
753         test_cmp expect actual &&
754         git merge --continue 2>err &&
755         test_i18ngrep "Applied autostash." err &&
756         git show HEAD:file >merge-result &&
757         test_cmp result.1-5 merge-result &&
758         test_cmp result.1-5-9 file
759 '
760
761 test_expect_success 'aborted merge (merge --abort) with --no-commit and --autostash' '
762         git reset --hard c1 &&
763         git merge-file file file.orig file.9 &&
764         git diff >expect &&
765         git merge --no-commit --autostash c2 &&
766         git stash show -p MERGE_AUTOSTASH >actual &&
767         test_cmp expect actual &&
768         git merge --abort 2>err &&
769         test_i18ngrep "Applied autostash." err &&
770         git diff >actual &&
771         test_cmp expect actual
772 '
773
774 test_expect_success 'aborted merge (reset --hard) with --no-commit and --autostash' '
775         git reset --hard c1 &&
776         git merge-file file file.orig file.9 &&
777         git diff >expect &&
778         git merge --no-commit --autostash c2 &&
779         git stash show -p MERGE_AUTOSTASH >actual &&
780         test_cmp expect actual &&
781         git reset --hard 2>err &&
782         test_i18ngrep "Autostash exists; creating a new stash entry." err &&
783         git diff --exit-code
784 '
785
786 test_expect_success 'quit merge with --no-commit and --autostash' '
787         git reset --hard c1 &&
788         git merge-file file file.orig file.9 &&
789         git diff >expect &&
790         git merge --no-commit --autostash c2 &&
791         git stash show -p MERGE_AUTOSTASH >actual &&
792         test_cmp expect actual &&
793         git diff HEAD >expect &&
794         git merge --quit 2>err &&
795         test_i18ngrep "Autostash exists; creating a new stash entry." err &&
796         git diff HEAD >actual &&
797         test_cmp expect actual
798 '
799
800 test_expect_success 'merge with conflicted --autostash changes' '
801         git reset --hard c1 &&
802         git merge-file file file.orig file.9y &&
803         git diff >expect &&
804         test_when_finished "test_might_fail git stash drop" &&
805         git merge --autostash c3 2>err &&
806         test_i18ngrep "Applying autostash resulted in conflicts." err &&
807         git show HEAD:file >merge-result &&
808         test_cmp result.1-9 merge-result &&
809         git stash show -p >actual &&
810         test_cmp expect actual
811 '
812
813 cat >expected.branch <<\EOF
814 Merge branch 'c5-branch' (early part)
815 EOF
816 cat >expected.tag <<\EOF
817 Merge commit 'c5~1'
818 EOF
819
820 test_expect_success 'merge early part of c2' '
821         git reset --hard c3 &&
822         echo c4 >c4.c &&
823         git add c4.c &&
824         git commit -m c4 &&
825         git tag c4 &&
826         echo c5 >c5.c &&
827         git add c5.c &&
828         git commit -m c5 &&
829         git tag c5 &&
830         git reset --hard c3 &&
831         echo c6 >c6.c &&
832         git add c6.c &&
833         git commit -m c6 &&
834         git tag c6 &&
835         git branch -f c5-branch c5 &&
836         git merge c5-branch~1 &&
837         git show -s --pretty=tformat:%s HEAD >actual.branch &&
838         git reset --keep HEAD^ &&
839         git merge c5~1 &&
840         git show -s --pretty=tformat:%s HEAD >actual.tag &&
841         test_cmp expected.branch actual.branch &&
842         test_cmp expected.tag actual.tag
843 '
844
845 test_debug 'git log --graph --decorate --oneline --all'
846
847 test_expect_success 'merge --no-ff --no-commit && commit' '
848         git reset --hard c0 &&
849         git merge --no-ff --no-commit c1 &&
850         EDITOR=: git commit &&
851         verify_parents $c0 $c1
852 '
853
854 test_debug 'git log --graph --decorate --oneline --all'
855
856 test_expect_success 'amending no-ff merge commit' '
857         EDITOR=: git commit --amend &&
858         verify_parents $c0 $c1
859 '
860
861 test_debug 'git log --graph --decorate --oneline --all'
862
863 cat >editor <<\EOF
864 #!/bin/sh
865 # Add a new message string that was not in the template
866 (
867         echo "Merge work done on the side branch c1"
868         echo
869         cat "$1"
870 ) >"$1.tmp" && mv "$1.tmp" "$1"
871 # strip comments and blank lines from end of message
872 sed -e '/^#/d' "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' >expected
873 EOF
874 chmod 755 editor
875
876 test_expect_success 'merge --no-ff --edit' '
877         git reset --hard c0 &&
878         EDITOR=./editor git merge --no-ff --edit c1 &&
879         verify_parents $c0 $c1 &&
880         git cat-file commit HEAD >raw &&
881         grep "work done on the side branch" raw &&
882         sed "1,/^$/d" >actual raw &&
883         test_cmp expected actual
884 '
885
886 test_expect_success 'merge annotated/signed tag w/o tracking' '
887         test_when_finished "rm -rf dst; git tag -d anno1" &&
888         git tag -a -m "anno c1" anno1 c1 &&
889         git init dst &&
890         git rev-parse c1 >dst/expect &&
891         (
892                 # c0 fast-forwards to c1 but because this repository
893                 # is not a "downstream" whose refs/tags follows along
894                 # tag from the "upstream", this pull defaults to --no-ff
895                 cd dst &&
896                 git pull .. c0 &&
897                 git pull .. anno1 &&
898                 git rev-parse HEAD^2 >actual &&
899                 test_cmp expect actual
900         )
901 '
902
903 test_expect_success 'merge annotated/signed tag w/ tracking' '
904         test_when_finished "rm -rf dst; git tag -d anno1" &&
905         git tag -a -m "anno c1" anno1 c1 &&
906         git init dst &&
907         git rev-parse c1 >dst/expect &&
908         (
909                 # c0 fast-forwards to c1 and because this repository
910                 # is a "downstream" whose refs/tags follows along
911                 # tag from the "upstream", this pull defaults to --ff
912                 cd dst &&
913                 git remote add origin .. &&
914                 git pull origin c0 &&
915                 git fetch origin &&
916                 git merge anno1 &&
917                 git rev-parse HEAD >actual &&
918                 test_cmp expect actual
919         )
920 '
921
922 test_expect_success GPG 'merge --ff-only tag' '
923         git reset --hard c0 &&
924         git commit --allow-empty -m "A newer commit" &&
925         git tag -s -m "A newer commit" signed &&
926         git reset --hard c0 &&
927
928         git merge --ff-only signed &&
929         git rev-parse signed^0 >expect &&
930         git rev-parse HEAD >actual &&
931         test_cmp expect actual
932 '
933
934 test_expect_success GPG 'merge --no-edit tag should skip editor' '
935         git reset --hard c0 &&
936         git commit --allow-empty -m "A newer commit" &&
937         git tag -f -s -m "A newer commit" signed &&
938         git reset --hard c0 &&
939
940         EDITOR=false git merge --no-edit --no-ff signed &&
941         git rev-parse signed^0 >expect &&
942         git rev-parse HEAD^2 >actual &&
943         test_cmp expect actual
944 '
945
946 test_expect_success 'set up mod-256 conflict scenario' '
947         # 256 near-identical stanzas...
948         for i in $(test_seq 1 256); do
949                 for j in 1 2 3 4 5; do
950                         echo $i-$j
951                 done
952         done >file &&
953         git add file &&
954         git commit -m base &&
955
956         # one side changes the first line of each to "main"
957         sed s/-1/-main/ file >tmp &&
958         mv tmp file &&
959         git commit -am main &&
960
961         # and the other to "side"; merging the two will
962         # yield 256 separate conflicts
963         git checkout -b side HEAD^ &&
964         sed s/-1/-side/ file >tmp &&
965         mv tmp file &&
966         git commit -am side
967 '
968
969 test_expect_success 'merge detects mod-256 conflicts (recursive)' '
970         git reset --hard &&
971         test_must_fail git merge -s recursive main
972 '
973
974 test_expect_success 'merge detects mod-256 conflicts (resolve)' '
975         git reset --hard &&
976         test_must_fail git merge -s resolve main
977 '
978
979 test_expect_success 'merge nothing into void' '
980         git init void &&
981         (
982                 cd void &&
983                 git remote add up .. &&
984                 git fetch up &&
985                 test_must_fail git merge FETCH_HEAD
986         )
987 '
988
989 test_expect_success 'merge can be completed with --continue' '
990         git reset --hard c0 &&
991         git merge --no-ff --no-commit c1 &&
992         git merge --continue &&
993         verify_parents $c0 $c1
994 '
995
996 write_script .git/FAKE_EDITOR <<EOF
997 # kill -TERM command added below.
998 EOF
999
1000 test_expect_success EXECKEEPSPID 'killed merge can be completed with --continue' '
1001         git reset --hard c0 &&
1002         ! "$SHELL_PATH" -c '\''
1003           echo kill -TERM $$ >>.git/FAKE_EDITOR
1004           GIT_EDITOR=.git/FAKE_EDITOR
1005           export GIT_EDITOR
1006           exec git merge --no-ff --edit c1'\'' &&
1007         git merge --continue &&
1008         verify_parents $c0 $c1
1009 '
1010
1011 test_expect_success 'merge --quit' '
1012         git init merge-quit &&
1013         (
1014                 cd merge-quit &&
1015                 test_commit base &&
1016                 echo one >>base.t &&
1017                 git commit -am one &&
1018                 git branch one &&
1019                 git checkout base &&
1020                 echo two >>base.t &&
1021                 git commit -am two &&
1022                 test_must_fail git -c rerere.enabled=true merge one &&
1023                 test_path_is_file .git/MERGE_HEAD &&
1024                 test_path_is_file .git/MERGE_MODE &&
1025                 test_path_is_file .git/MERGE_MSG &&
1026                 git rerere status >rerere.before &&
1027                 git merge --quit &&
1028                 test_path_is_missing .git/MERGE_HEAD &&
1029                 test_path_is_missing .git/MERGE_MODE &&
1030                 test_path_is_missing .git/MERGE_MSG &&
1031                 git rerere status >rerere.after &&
1032                 test_must_be_empty rerere.after &&
1033                 ! test_cmp rerere.after rerere.before
1034         )
1035 '
1036
1037 test_expect_success 'merge suggests matching remote refname' '
1038         git commit --allow-empty -m not-local &&
1039         git update-ref refs/remotes/origin/not-local HEAD &&
1040         git reset --hard HEAD^ &&
1041
1042         # This is white-box testing hackery; we happen to know
1043         # that reading packed refs is more picky about the memory
1044         # ownership of strings we pass to for_each_ref() callbacks.
1045         git pack-refs --all --prune &&
1046
1047         test_must_fail git merge not-local 2>stderr &&
1048         grep origin/not-local stderr
1049 '
1050
1051 test_expect_success 'suggested names are not ambiguous' '
1052         git update-ref refs/heads/origin/not-local HEAD &&
1053         test_must_fail git merge not-local 2>stderr &&
1054         grep remotes/origin/not-local stderr
1055 '
1056
1057 test_done