setup: split "extensions found" messages into singular and plural
[git] / t / t7610-mergetool.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2008 Charles Bailey
4 #
5
6 test_description='git mergetool
7
8 Testing basic merge tool invocation'
9
10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12
13 . ./test-lib.sh
14
15 # All the mergetool test work by checking out a temporary branch based
16 # off 'branch1' and then merging in main and checking the results of
17 # running mergetool
18
19 test_expect_success 'setup' '
20         test_config rerere.enabled true &&
21         echo main >file1 &&
22         echo main spaced >"spaced name" &&
23         echo main file11 >file11 &&
24         echo main file12 >file12 &&
25         echo main file13 >file13 &&
26         echo main file14 >file14 &&
27         mkdir subdir &&
28         echo main sub >subdir/file3 &&
29         test_create_repo submod &&
30         (
31                 cd submod &&
32                 : >foo &&
33                 git add foo &&
34                 git commit -m "Add foo"
35         ) &&
36         git submodule add git://example.com/submod submod &&
37         git add file1 "spaced name" file1[1-4] subdir/file3 .gitmodules submod &&
38         git commit -m "add initial versions" &&
39
40         git checkout -b branch1 main &&
41         git submodule update -N &&
42         echo branch1 change >file1 &&
43         echo branch1 newfile >file2 &&
44         echo branch1 spaced >"spaced name" &&
45         echo branch1 both added >both &&
46         echo branch1 change file11 >file11 &&
47         echo branch1 change file13 >file13 &&
48         echo branch1 sub >subdir/file3 &&
49         (
50                 cd submod &&
51                 echo branch1 submodule >bar &&
52                 git add bar &&
53                 git commit -m "Add bar on branch1" &&
54                 git checkout -b submod-branch1
55         ) &&
56         git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
57         git add both &&
58         git rm file12 &&
59         git commit -m "branch1 changes" &&
60
61         git checkout -b delete-base branch1 &&
62         mkdir -p a/a &&
63         test_write_lines one two 3 4 >a/a/file.txt &&
64         git add a/a/file.txt &&
65         git commit -m"base file" &&
66         git checkout -b move-to-b delete-base &&
67         mkdir -p b/b &&
68         git mv a/a/file.txt b/b/file.txt &&
69         test_write_lines one two 4 >b/b/file.txt &&
70         git commit -a -m"move to b" &&
71         git checkout -b move-to-c delete-base &&
72         mkdir -p c/c &&
73         git mv a/a/file.txt c/c/file.txt &&
74         test_write_lines one two 3 >c/c/file.txt &&
75         git commit -a -m"move to c" &&
76
77         git checkout -b stash1 main &&
78         echo stash1 change file11 >file11 &&
79         git add file11 &&
80         git commit -m "stash1 changes" &&
81
82         git checkout -b stash2 main &&
83         echo stash2 change file11 >file11 &&
84         git add file11 &&
85         git commit -m "stash2 changes" &&
86
87         git checkout main &&
88         git submodule update -N &&
89         echo main updated >file1 &&
90         echo main new >file2 &&
91         echo main updated spaced >"spaced name" &&
92         echo main both added >both &&
93         echo main updated file12 >file12 &&
94         echo main updated file14 >file14 &&
95         echo main new sub >subdir/file3 &&
96         (
97                 cd submod &&
98                 echo main submodule >bar &&
99                 git add bar &&
100                 git commit -m "Add bar on main" &&
101                 git checkout -b submod-main
102         ) &&
103         git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
104         git add both &&
105         git rm file11 &&
106         git commit -m "main updates" &&
107
108         git clean -fdx &&
109         git checkout -b order-file-start main &&
110         echo start >a &&
111         echo start >b &&
112         git add a b &&
113         git commit -m start &&
114         git checkout -b order-file-side1 order-file-start &&
115         echo side1 >a &&
116         echo side1 >b &&
117         git add a b &&
118         git commit -m side1 &&
119         git checkout -b order-file-side2 order-file-start &&
120         echo side2 >a &&
121         echo side2 >b &&
122         git add a b &&
123         git commit -m side2 &&
124
125         git config merge.tool mytool &&
126         git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
127         git config mergetool.mytool.trustExitCode true &&
128         git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
129         git config mergetool.mybase.trustExitCode true
130 '
131
132 test_expect_success 'custom mergetool' '
133         test_when_finished "git reset --hard" &&
134         git checkout -b test$test_count branch1 &&
135         git submodule update -N &&
136         test_must_fail git merge main &&
137         yes "" | git mergetool both &&
138         yes "" | git mergetool file1 file1 &&
139         yes "" | git mergetool file2 "spaced name" &&
140         yes "" | git mergetool subdir/file3 &&
141         yes "d" | git mergetool file11 &&
142         yes "d" | git mergetool file12 &&
143         yes "l" | git mergetool submod &&
144         echo "main updated" >expect &&
145         test_cmp expect file1 &&
146         echo "main new" >expect &&
147         test_cmp expect file2 &&
148         echo "main new sub" >expect &&
149         test_cmp expect subdir/file3 &&
150         echo "branch1 submodule" >expect &&
151         test_cmp expect submod/bar &&
152         git commit -m "branch1 resolved with mergetool"
153 '
154
155 test_expect_success 'gui mergetool' '
156         test_config merge.guitool myguitool &&
157         test_config mergetool.myguitool.cmd "(printf \"gui \" && cat \"\$REMOTE\") >\"\$MERGED\"" &&
158         test_config mergetool.myguitool.trustExitCode true &&
159         test_when_finished "git reset --hard" &&
160         git checkout -b test$test_count branch1 &&
161         git submodule update -N &&
162         test_must_fail git merge main &&
163         yes "" | git mergetool --gui both &&
164         yes "" | git mergetool -g file1 file1 &&
165         yes "" | git mergetool --gui file2 "spaced name" &&
166         yes "" | git mergetool --gui subdir/file3 &&
167         yes "d" | git mergetool --gui file11 &&
168         yes "d" | git mergetool --gui file12 &&
169         yes "l" | git mergetool --gui submod &&
170         echo "gui main updated" >expect &&
171         test_cmp expect file1 &&
172         echo "gui main new" >expect &&
173         test_cmp expect file2 &&
174         echo "gui main new sub" >expect &&
175         test_cmp expect subdir/file3 &&
176         echo "branch1 submodule" >expect &&
177         test_cmp expect submod/bar &&
178         git commit -m "branch1 resolved with mergetool"
179 '
180
181 test_expect_success 'gui mergetool without merge.guitool set falls back to merge.tool' '
182         test_when_finished "git reset --hard" &&
183         git checkout -b test$test_count branch1 &&
184         git submodule update -N &&
185         test_must_fail git merge main &&
186         yes "" | git mergetool --gui both &&
187         yes "" | git mergetool -g file1 file1 &&
188         yes "" | git mergetool --gui file2 "spaced name" &&
189         yes "" | git mergetool --gui subdir/file3 &&
190         yes "d" | git mergetool --gui file11 &&
191         yes "d" | git mergetool --gui file12 &&
192         yes "l" | git mergetool --gui submod &&
193         echo "main updated" >expect &&
194         test_cmp expect file1 &&
195         echo "main new" >expect &&
196         test_cmp expect file2 &&
197         echo "main new sub" >expect &&
198         test_cmp expect subdir/file3 &&
199         echo "branch1 submodule" >expect &&
200         test_cmp expect submod/bar &&
201         git commit -m "branch1 resolved with mergetool"
202 '
203
204 test_expect_success 'mergetool crlf' '
205         test_when_finished "git reset --hard" &&
206         # This test_config line must go after the above reset line so that
207         # core.autocrlf is unconfigured before reset runs.  (The
208         # test_config command uses test_when_finished internally and
209         # test_when_finished is LIFO.)
210         test_config core.autocrlf true &&
211         git checkout -b test$test_count branch1 &&
212         test_must_fail git merge main &&
213         yes "" | git mergetool file1 &&
214         yes "" | git mergetool file2 &&
215         yes "" | git mergetool "spaced name" &&
216         yes "" | git mergetool both &&
217         yes "" | git mergetool subdir/file3 &&
218         yes "d" | git mergetool file11 &&
219         yes "d" | git mergetool file12 &&
220         yes "r" | git mergetool submod &&
221         test "$(printf x | cat file1 -)" = "$(printf "main updated\r\nx")" &&
222         test "$(printf x | cat file2 -)" = "$(printf "main new\r\nx")" &&
223         test "$(printf x | cat subdir/file3 -)" = "$(printf "main new sub\r\nx")" &&
224         git submodule update -N &&
225         echo "main submodule" >expect &&
226         test_cmp expect submod/bar &&
227         git commit -m "branch1 resolved with mergetool - autocrlf"
228 '
229
230 test_expect_success 'mergetool in subdir' '
231         test_when_finished "git reset --hard" &&
232         git checkout -b test$test_count branch1 &&
233         git submodule update -N &&
234         (
235                 cd subdir &&
236                 test_must_fail git merge main &&
237                 yes "" | git mergetool file3 &&
238                 echo "main new sub" >expect &&
239                 test_cmp expect file3
240         )
241 '
242
243 test_expect_success 'mergetool on file in parent dir' '
244         test_when_finished "git reset --hard" &&
245         git checkout -b test$test_count branch1 &&
246         git submodule update -N &&
247         (
248                 cd subdir &&
249                 test_must_fail git merge main &&
250                 yes "" | git mergetool file3 &&
251                 yes "" | git mergetool ../file1 &&
252                 yes "" | git mergetool ../file2 ../spaced\ name &&
253                 yes "" | git mergetool ../both &&
254                 yes "d" | git mergetool ../file11 &&
255                 yes "d" | git mergetool ../file12 &&
256                 yes "l" | git mergetool ../submod &&
257                 echo "main updated" >expect &&
258                 test_cmp expect ../file1 &&
259                 echo "main new" >expect &&
260                 test_cmp expect ../file2 &&
261                 echo "branch1 submodule" >expect &&
262                 test_cmp expect ../submod/bar &&
263                 git commit -m "branch1 resolved with mergetool - subdir"
264         )
265 '
266
267 test_expect_success 'mergetool skips autoresolved' '
268         test_when_finished "git reset --hard" &&
269         git checkout -b test$test_count branch1 &&
270         git submodule update -N &&
271         test_must_fail git merge main &&
272         test -n "$(git ls-files -u)" &&
273         yes "d" | git mergetool file11 &&
274         yes "d" | git mergetool file12 &&
275         yes "l" | git mergetool submod &&
276         output="$(git mergetool --no-prompt)" &&
277         test "$output" = "No files need merging"
278 '
279
280 test_expect_success 'mergetool merges all from subdir (rerere disabled)' '
281         test_when_finished "git reset --hard" &&
282         git checkout -b test$test_count branch1 &&
283         test_config rerere.enabled false &&
284         (
285                 cd subdir &&
286                 test_must_fail git merge main &&
287                 yes "r" | git mergetool ../submod &&
288                 yes "d" "d" | git mergetool --no-prompt &&
289                 echo "main updated" >expect &&
290                 test_cmp expect ../file1 &&
291                 echo "main new" >expect &&
292                 test_cmp expect ../file2 &&
293                 echo "main new sub" >expect &&
294                 test_cmp expect file3 &&
295                 ( cd .. && git submodule update -N ) &&
296                 echo "main submodule" >expect &&
297                 test_cmp expect ../submod/bar &&
298                 git commit -m "branch2 resolved by mergetool from subdir"
299         )
300 '
301
302 test_expect_success 'mergetool merges all from subdir (rerere enabled)' '
303         test_when_finished "git reset --hard" &&
304         git checkout -b test$test_count branch1 &&
305         test_config rerere.enabled true &&
306         rm -rf .git/rr-cache &&
307         (
308                 cd subdir &&
309                 test_must_fail git merge main &&
310                 yes "r" | git mergetool ../submod &&
311                 yes "d" "d" | git mergetool --no-prompt &&
312                 echo "main updated" >expect &&
313                 test_cmp expect ../file1 &&
314                 echo "main new" >expect &&
315                 test_cmp expect ../file2 &&
316                 echo "main new sub" >expect &&
317                 test_cmp expect file3 &&
318                 ( cd .. && git submodule update -N ) &&
319                 echo "main submodule" >expect &&
320                 test_cmp expect ../submod/bar &&
321                 git commit -m "branch2 resolved by mergetool from subdir"
322         )
323 '
324
325 test_expect_success 'mergetool skips resolved paths when rerere is active' '
326         test_when_finished "git reset --hard" &&
327         test_config rerere.enabled true &&
328         rm -rf .git/rr-cache &&
329         git checkout -b test$test_count branch1 &&
330         git submodule update -N &&
331         test_must_fail git merge main &&
332         yes "l" | git mergetool --no-prompt submod &&
333         yes "d" "d" | git mergetool --no-prompt &&
334         git submodule update -N &&
335         output="$(yes "n" | git mergetool --no-prompt)" &&
336         test "$output" = "No files need merging"
337 '
338
339 test_expect_success 'conflicted stash sets up rerere'  '
340         test_when_finished "git reset --hard" &&
341         test_config rerere.enabled true &&
342         git checkout stash1 &&
343         echo "Conflicting stash content" >file11 &&
344         git stash &&
345
346         git checkout --detach stash2 &&
347         test_must_fail git stash apply &&
348
349         test -n "$(git ls-files -u)" &&
350         conflicts="$(git rerere remaining)" &&
351         test "$conflicts" = "file11" &&
352         output="$(git mergetool --no-prompt)" &&
353         test "$output" != "No files need merging" &&
354
355         git commit -am "save the stash resolution" &&
356
357         git reset --hard stash2 &&
358         test_must_fail git stash apply &&
359
360         test -n "$(git ls-files -u)" &&
361         conflicts="$(git rerere remaining)" &&
362         test -z "$conflicts" &&
363         output="$(git mergetool --no-prompt)" &&
364         test "$output" = "No files need merging"
365 '
366
367 test_expect_success 'mergetool takes partial path' '
368         test_when_finished "git reset --hard" &&
369         test_config rerere.enabled false &&
370         git checkout -b test$test_count branch1 &&
371         git submodule update -N &&
372         test_must_fail git merge main &&
373
374         yes "" | git mergetool subdir &&
375
376         echo "main new sub" >expect &&
377         test_cmp expect subdir/file3
378 '
379
380 test_expect_success 'mergetool delete/delete conflict' '
381         test_when_finished "git reset --hard" &&
382         git checkout -b test$test_count move-to-c &&
383         test_must_fail git merge move-to-b &&
384         echo d | git mergetool a/a/file.txt &&
385         ! test -f a/a/file.txt &&
386         git reset --hard &&
387         test_must_fail git merge move-to-b &&
388         echo m | git mergetool a/a/file.txt &&
389         test -f b/b/file.txt &&
390         git reset --hard &&
391         test_must_fail git merge move-to-b &&
392         ! echo a | git mergetool a/a/file.txt &&
393         ! test -f a/a/file.txt
394 '
395
396 test_expect_success 'mergetool produces no errors when keepBackup is used' '
397         test_when_finished "git reset --hard" &&
398         git checkout -b test$test_count move-to-c &&
399         test_config mergetool.keepBackup true &&
400         test_must_fail git merge move-to-b &&
401         echo d | git mergetool a/a/file.txt 2>actual &&
402         test_must_be_empty actual &&
403         ! test -d a
404 '
405
406 test_expect_success 'mergetool honors tempfile config for deleted files' '
407         test_when_finished "git reset --hard" &&
408         git checkout -b test$test_count move-to-c &&
409         test_config mergetool.keepTemporaries false &&
410         test_must_fail git merge move-to-b &&
411         echo d | git mergetool a/a/file.txt &&
412         ! test -d a
413 '
414
415 test_expect_success 'mergetool keeps tempfiles when aborting delete/delete' '
416         test_when_finished "git reset --hard" &&
417         test_when_finished "git clean -fdx" &&
418         git checkout -b test$test_count move-to-c &&
419         test_config mergetool.keepTemporaries true &&
420         test_must_fail git merge move-to-b &&
421         ! test_write_lines a n | git mergetool a/a/file.txt &&
422         test -d a/a &&
423         cat >expect <<-\EOF &&
424         file_BASE_.txt
425         file_LOCAL_.txt
426         file_REMOTE_.txt
427         EOF
428         ls -1 a/a | sed -e "s/[0-9]*//g" >actual &&
429         test_cmp expect actual
430 '
431
432 test_expect_success 'deleted vs modified submodule' '
433         test_when_finished "git reset --hard" &&
434         git checkout -b test$test_count branch1 &&
435         git submodule update -N &&
436         mv submod submod-movedaside &&
437         git rm --cached submod &&
438         git commit -m "Submodule deleted from branch" &&
439         git checkout -b test$test_count.a test$test_count &&
440         test_must_fail git merge main &&
441         test -n "$(git ls-files -u)" &&
442         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
443         yes "" | git mergetool both &&
444         yes "d" | git mergetool file11 file12 &&
445         yes "r" | git mergetool submod &&
446         rmdir submod && mv submod-movedaside submod &&
447         echo "branch1 submodule" >expect &&
448         test_cmp expect submod/bar &&
449         git submodule update -N &&
450         echo "main submodule" >expect &&
451         test_cmp expect submod/bar &&
452         output="$(git mergetool --no-prompt)" &&
453         test "$output" = "No files need merging" &&
454         git commit -m "Merge resolved by keeping module" &&
455
456         mv submod submod-movedaside &&
457         git checkout -b test$test_count.b test$test_count &&
458         git submodule update -N &&
459         test_must_fail git merge main &&
460         test -n "$(git ls-files -u)" &&
461         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
462         yes "" | git mergetool both &&
463         yes "d" | git mergetool file11 file12 &&
464         yes "l" | git mergetool submod &&
465         test ! -e submod &&
466         output="$(git mergetool --no-prompt)" &&
467         test "$output" = "No files need merging" &&
468         git commit -m "Merge resolved by deleting module" &&
469
470         mv submod-movedaside submod &&
471         git checkout -b test$test_count.c main &&
472         git submodule update -N &&
473         test_must_fail git merge test$test_count &&
474         test -n "$(git ls-files -u)" &&
475         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
476         yes "" | git mergetool both &&
477         yes "d" | git mergetool file11 file12 &&
478         yes "r" | git mergetool submod &&
479         test ! -e submod &&
480         test -d submod.orig &&
481         git submodule update -N &&
482         output="$(git mergetool --no-prompt)" &&
483         test "$output" = "No files need merging" &&
484         git commit -m "Merge resolved by deleting module" &&
485         mv submod.orig submod &&
486
487         git checkout -b test$test_count.d main &&
488         git submodule update -N &&
489         test_must_fail git merge test$test_count &&
490         test -n "$(git ls-files -u)" &&
491         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
492         yes "" | git mergetool both &&
493         yes "d" | git mergetool file11 file12 &&
494         yes "l" | git mergetool submod &&
495         echo "main submodule" >expect &&
496         test_cmp expect submod/bar &&
497         git submodule update -N &&
498         echo "main submodule" >expect &&
499         test_cmp expect submod/bar &&
500         output="$(git mergetool --no-prompt)" &&
501         test "$output" = "No files need merging" &&
502         git commit -m "Merge resolved by keeping module"
503 '
504
505 test_expect_success 'file vs modified submodule' '
506         test_when_finished "git reset --hard" &&
507         git checkout -b test$test_count branch1 &&
508         git submodule update -N &&
509         mv submod submod-movedaside &&
510         git rm --cached submod &&
511         echo not a submodule >submod &&
512         git add submod &&
513         git commit -m "Submodule path becomes file" &&
514         git checkout -b test$test_count.a branch1 &&
515         test_must_fail git merge main &&
516         test -n "$(git ls-files -u)" &&
517         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
518         yes "" | git mergetool both &&
519         yes "d" | git mergetool file11 file12 &&
520         yes "r" | git mergetool submod &&
521         rmdir submod && mv submod-movedaside submod &&
522         echo "branch1 submodule" >expect &&
523         test_cmp expect submod/bar &&
524         git submodule update -N &&
525         echo "main submodule" >expect &&
526         test_cmp expect submod/bar &&
527         output="$(git mergetool --no-prompt)" &&
528         test "$output" = "No files need merging" &&
529         git commit -m "Merge resolved by keeping module" &&
530
531         mv submod submod-movedaside &&
532         git checkout -b test$test_count.b test$test_count &&
533         test_must_fail git merge main &&
534         test -n "$(git ls-files -u)" &&
535         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
536         yes "" | git mergetool both &&
537         yes "d" | git mergetool file11 file12 &&
538         if test "$GIT_TEST_MERGE_ALGORITHM" = ort
539         then
540                 yes "c" | git mergetool submod~HEAD &&
541                 git rm submod &&
542                 git mv submod~HEAD submod
543         else
544                 yes "l" | git mergetool submod
545         fi &&
546         git submodule update -N &&
547         echo "not a submodule" >expect &&
548         test_cmp expect submod &&
549         output="$(git mergetool --no-prompt)" &&
550         test "$output" = "No files need merging" &&
551         git commit -m "Merge resolved by keeping file" &&
552
553         git checkout -b test$test_count.c main &&
554         rmdir submod && mv submod-movedaside submod &&
555         test ! -e submod.orig &&
556         git submodule update -N &&
557         test_must_fail git merge test$test_count &&
558         test -n "$(git ls-files -u)" &&
559         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
560         yes "" | git mergetool both &&
561         yes "d" | git mergetool file11 file12 &&
562         if test "$GIT_TEST_MERGE_ALGORITHM" = ort
563         then
564                 mv submod submod.orig &&
565                 git rm --cached submod &&
566                 yes "c" | git mergetool submod~test19 &&
567                 git mv submod~test19 submod
568         else
569                 yes "r" | git mergetool submod
570         fi &&
571         test -d submod.orig &&
572         git submodule update -N &&
573         echo "not a submodule" >expect &&
574         test_cmp expect submod &&
575         output="$(git mergetool --no-prompt)" &&
576         test "$output" = "No files need merging" &&
577         git commit -m "Merge resolved by keeping file" &&
578
579         git checkout -b test$test_count.d main &&
580         rmdir submod && mv submod.orig submod &&
581         git submodule update -N &&
582         test_must_fail git merge test$test_count &&
583         test -n "$(git ls-files -u)" &&
584         yes "" | git mergetool file1 file2 spaced\ name subdir/file3 &&
585         yes "" | git mergetool both &&
586         yes "d" | git mergetool file11 file12 &&
587         yes "l" | git mergetool submod &&
588         if test "$GIT_TEST_MERGE_ALGORITHM" = ort
589         then
590                 yes "d" | git mergetool submod~test19
591         fi &&
592         echo "main submodule" >expect &&
593         test_cmp expect submod/bar &&
594         git submodule update -N &&
595         echo "main submodule" >expect &&
596         test_cmp expect submod/bar &&
597         output="$(git mergetool --no-prompt)" &&
598         test "$output" = "No files need merging" &&
599         git commit -m "Merge resolved by keeping module"
600 '
601
602 test_expect_success 'submodule in subdirectory' '
603         test_when_finished "git reset --hard" &&
604         git checkout -b test$test_count branch1 &&
605         git submodule update -N &&
606         (
607                 cd subdir &&
608                 test_create_repo subdir_module &&
609                 (
610                 cd subdir_module &&
611                 : >file15 &&
612                 git add file15 &&
613                 git commit -m "add initial versions"
614                 )
615         ) &&
616         test_when_finished "rm -rf subdir/subdir_module" &&
617         git submodule add git://example.com/subsubmodule subdir/subdir_module &&
618         git add subdir/subdir_module &&
619         git commit -m "add submodule in subdirectory" &&
620
621         git checkout -b test$test_count.a test$test_count &&
622         git submodule update -N &&
623         (
624         cd subdir/subdir_module &&
625                 git checkout -b super10.a &&
626                 echo test$test_count.a >file15 &&
627                 git add file15 &&
628                 git commit -m "on branch 10.a"
629         ) &&
630         git add subdir/subdir_module &&
631         git commit -m "change submodule in subdirectory on test$test_count.a" &&
632
633         git checkout -b test$test_count.b test$test_count &&
634         git submodule update -N &&
635         (
636                 cd subdir/subdir_module &&
637                 git checkout -b super10.b &&
638                 echo test$test_count.b >file15 &&
639                 git add file15 &&
640                 git commit -m "on branch 10.b"
641         ) &&
642         git add subdir/subdir_module &&
643         git commit -m "change submodule in subdirectory on test$test_count.b" &&
644
645         test_must_fail git merge test$test_count.a &&
646         (
647                 cd subdir &&
648                 yes "l" | git mergetool subdir_module
649         ) &&
650         echo "test$test_count.b" >expect &&
651         test_cmp expect subdir/subdir_module/file15 &&
652         git submodule update -N &&
653         echo "test$test_count.b" >expect &&
654         test_cmp expect subdir/subdir_module/file15 &&
655         git reset --hard &&
656         git submodule update -N &&
657
658         test_must_fail git merge test$test_count.a &&
659         yes "r" | git mergetool subdir/subdir_module &&
660         echo "test$test_count.b" >expect &&
661         test_cmp expect subdir/subdir_module/file15 &&
662         git submodule update -N &&
663         echo "test$test_count.a" >expect &&
664         test_cmp expect subdir/subdir_module/file15 &&
665         git commit -m "branch1 resolved with mergetool"
666 '
667
668 test_expect_success 'directory vs modified submodule' '
669         test_when_finished "git reset --hard" &&
670         git checkout -b test$test_count branch1 &&
671         mv submod submod-movedaside &&
672         git rm --cached submod &&
673         mkdir submod &&
674         echo not a submodule >submod/file16 &&
675         git add submod/file16 &&
676         git commit -m "Submodule path becomes directory" &&
677
678         test_must_fail git merge main &&
679         test -n "$(git ls-files -u)" &&
680         yes "l" | git mergetool submod &&
681         echo "not a submodule" >expect &&
682         test_cmp expect submod/file16 &&
683         rm -rf submod.orig &&
684
685         git reset --hard &&
686         test_must_fail git merge main &&
687         test -n "$(git ls-files -u)" &&
688         test ! -e submod.orig &&
689         if test "$GIT_TEST_MERGE_ALGORITHM" = ort
690         then
691                 yes "r" | git mergetool submod~main &&
692                 git mv submod submod.orig &&
693                 git mv submod~main submod
694         else
695                 yes "r" | git mergetool submod
696         fi &&
697         test -d submod.orig &&
698         echo "not a submodule" >expect &&
699         test_cmp expect submod.orig/file16 &&
700         rm -r submod.orig &&
701         mv submod-movedaside/.git submod &&
702         ( cd submod && git clean -f && git reset --hard ) &&
703         git submodule update -N &&
704         echo "main submodule" >expect &&
705         test_cmp expect submod/bar &&
706         git reset --hard &&
707         rm -rf submod-movedaside &&
708
709         git checkout -b test$test_count.c main &&
710         git submodule update -N &&
711         test_must_fail git merge test$test_count &&
712         test -n "$(git ls-files -u)" &&
713         yes "l" | git mergetool submod &&
714         git submodule update -N &&
715         echo "main submodule" >expect &&
716         test_cmp expect submod/bar &&
717
718         git reset --hard &&
719         git submodule update -N &&
720         test_must_fail git merge test$test_count &&
721         test -n "$(git ls-files -u)" &&
722         test ! -e submod.orig &&
723         yes "r" | git mergetool submod &&
724         echo "not a submodule" >expect &&
725         test_cmp expect submod/file16 &&
726
727         git reset --hard main &&
728         ( cd submod && git clean -f && git reset --hard ) &&
729         git submodule update -N
730 '
731
732 test_expect_success 'file with no base' '
733         test_when_finished "git reset --hard" &&
734         git checkout -b test$test_count branch1 &&
735         test_must_fail git merge main &&
736         git mergetool --no-prompt --tool mybase -- both &&
737         test_must_be_empty both
738 '
739
740 test_expect_success 'custom commands override built-ins' '
741         test_when_finished "git reset --hard" &&
742         git checkout -b test$test_count branch1 &&
743         test_config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
744         test_config mergetool.defaults.trustExitCode true &&
745         test_must_fail git merge main &&
746         git mergetool --no-prompt --tool defaults -- both &&
747         echo main both added >expected &&
748         test_cmp expected both
749 '
750
751 test_expect_success 'filenames seen by tools start with ./' '
752         test_when_finished "git reset --hard" &&
753         git checkout -b test$test_count branch1 &&
754         test_config mergetool.writeToTemp false &&
755         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
756         test_config mergetool.myecho.trustExitCode true &&
757         test_must_fail git merge main &&
758         git mergetool --no-prompt --tool myecho -- both >actual &&
759         grep ^\./both_LOCAL_ actual
760 '
761
762 test_lazy_prereq MKTEMP '
763         tempdir=$(mktemp -d -t foo.XXXXXX) &&
764         test -d "$tempdir" &&
765         rmdir "$tempdir"
766 '
767
768 test_expect_success MKTEMP 'temporary filenames are used with mergetool.writeToTemp' '
769         test_when_finished "git reset --hard" &&
770         git checkout -b test$test_count branch1 &&
771         test_config mergetool.writeToTemp true &&
772         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
773         test_config mergetool.myecho.trustExitCode true &&
774         test_must_fail git merge main &&
775         git mergetool --no-prompt --tool myecho -- both >actual &&
776         ! grep ^\./both_LOCAL_ actual &&
777         grep /both_LOCAL_ actual
778 '
779
780 test_expect_success 'diff.orderFile configuration is honored' '
781         test_when_finished "git reset --hard" &&
782         git checkout -b test$test_count order-file-side2 &&
783         test_config diff.orderFile order-file &&
784         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
785         test_config mergetool.myecho.trustExitCode true &&
786         echo b >order-file &&
787         echo a >>order-file &&
788         test_must_fail git merge order-file-side1 &&
789         cat >expect <<-\EOF &&
790                 Merging:
791                 b
792                 a
793         EOF
794
795         # make sure "order-file" that is ambiguous between
796         # rev and path is understood correctly.
797         git branch order-file HEAD &&
798
799         git mergetool --no-prompt --tool myecho >output &&
800         git grep --no-index -h -A2 Merging: output >actual &&
801         test_cmp expect actual
802 '
803 test_expect_success 'mergetool -Oorder-file is honored' '
804         test_when_finished "git reset --hard" &&
805         git checkout -b test$test_count order-file-side2 &&
806         test_config diff.orderFile order-file &&
807         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
808         test_config mergetool.myecho.trustExitCode true &&
809         echo b >order-file &&
810         echo a >>order-file &&
811         test_must_fail git merge order-file-side1 &&
812         cat >expect <<-\EOF &&
813                 Merging:
814                 a
815                 b
816         EOF
817         git mergetool -O/dev/null --no-prompt --tool myecho >output &&
818         git grep --no-index -h -A2 Merging: output >actual &&
819         test_cmp expect actual &&
820         git reset --hard &&
821
822         git config --unset diff.orderFile &&
823         test_must_fail git merge order-file-side1 &&
824         cat >expect <<-\EOF &&
825                 Merging:
826                 b
827                 a
828         EOF
829         git mergetool -Oorder-file --no-prompt --tool myecho >output &&
830         git grep --no-index -h -A2 Merging: output >actual &&
831         test_cmp expect actual
832 '
833
834 test_expect_success 'mergetool --tool-help shows recognized tools' '
835         # Check a few known tools are correctly shown
836         git mergetool --tool-help >mergetools &&
837         grep vimdiff mergetools &&
838         grep vimdiff3 mergetools &&
839         grep gvimdiff2 mergetools &&
840         grep araxis mergetools &&
841         grep xxdiff mergetools &&
842         grep meld mergetools
843 '
844
845 test_expect_success 'mergetool hideResolved' '
846         test_config mergetool.hideResolved true &&
847         test_when_finished "git reset --hard" &&
848         git checkout -b test${test_count}_b main &&
849         test_write_lines >file1 base "" a &&
850         git commit -a -m "base" &&
851         test_write_lines >file1 base "" c &&
852         git commit -a -m "remote update" &&
853         git checkout -b test${test_count}_a HEAD~ &&
854         test_write_lines >file1 local "" b &&
855         git commit -a -m "local update" &&
856         test_must_fail git merge test${test_count}_b &&
857         yes "" | git mergetool file1 &&
858         test_write_lines >expect local "" c &&
859         test_cmp expect file1 &&
860         git commit -m "test resolved with mergetool"
861 '
862
863 test_done