Merge branch 'pp/maint-doc-pager-config'
[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 . ./test-lib.sh
11
12 # All the mergetool test work by checking out a temporary branch based
13 # off 'branch1' and then merging in master and checking the results of
14 # running mergetool
15
16 test_expect_success 'setup' '
17     git config rerere.enabled true &&
18     echo master >file1 &&
19     echo master spaced >"spaced name" &&
20     echo master file11 >file11 &&
21     echo master file12 >file12 &&
22     echo master file13 >file13 &&
23     echo master file14 >file14 &&
24     mkdir subdir &&
25     echo master sub >subdir/file3 &&
26     test_create_repo submod &&
27     (
28         cd submod &&
29         : >foo &&
30         git add foo &&
31         git commit -m "Add foo"
32     ) &&
33     git submodule add git://example.com/submod submod &&
34     git add file1 "spaced name" file1[1-4] subdir/file3 .gitmodules submod &&
35     git commit -m "add initial versions" &&
36
37     git checkout -b branch1 master &&
38     git submodule update -N &&
39     echo branch1 change >file1 &&
40     echo branch1 newfile >file2 &&
41     echo branch1 spaced >"spaced name" &&
42     echo branch1 both added >both &&
43     echo branch1 change file11 >file11 &&
44     echo branch1 change file13 >file13 &&
45     echo branch1 sub >subdir/file3 &&
46     (
47         cd submod &&
48         echo branch1 submodule >bar &&
49         git add bar &&
50         git commit -m "Add bar on branch1" &&
51         git checkout -b submod-branch1
52     ) &&
53     git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
54     git add both &&
55     git rm file12 &&
56     git commit -m "branch1 changes" &&
57
58     git checkout -b stash1 master &&
59     echo stash1 change file11 >file11 &&
60     git add file11 &&
61     git commit -m "stash1 changes" &&
62
63     git checkout -b stash2 master &&
64     echo stash2 change file11 >file11 &&
65     git add file11 &&
66     git commit -m "stash2 changes" &&
67
68     git checkout master &&
69     git submodule update -N &&
70     echo master updated >file1 &&
71     echo master new >file2 &&
72     echo master updated spaced >"spaced name" &&
73     echo master both added >both &&
74     echo master updated file12 >file12 &&
75     echo master updated file14 >file14 &&
76     echo master new sub >subdir/file3 &&
77     (
78         cd submod &&
79         echo master submodule >bar &&
80         git add bar &&
81         git commit -m "Add bar on master" &&
82         git checkout -b submod-master
83     ) &&
84     git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
85     git add both &&
86     git rm file11 &&
87     git commit -m "master updates" &&
88
89     git config merge.tool mytool &&
90     git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
91     git config mergetool.mytool.trustExitCode true &&
92     git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
93     git config mergetool.mybase.trustExitCode true
94 '
95
96 test_expect_success 'custom mergetool' '
97     git checkout -b test1 branch1 &&
98     git submodule update -N &&
99     test_must_fail git merge master >/dev/null 2>&1 &&
100     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
101     ( yes "" | git mergetool file1 file1 ) &&
102     ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
103     ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
104     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
105     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
106     ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
107     test "$(cat file1)" = "master updated" &&
108     test "$(cat file2)" = "master new" &&
109     test "$(cat subdir/file3)" = "master new sub" &&
110     test "$(cat submod/bar)" = "branch1 submodule" &&
111     git commit -m "branch1 resolved with mergetool"
112 '
113
114 test_expect_success 'mergetool crlf' '
115     git config core.autocrlf true &&
116     git checkout -b test2 branch1 &&
117     test_must_fail git merge master >/dev/null 2>&1 &&
118     ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
119     ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
120     ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
121     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
122     ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
123     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
124     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
125     ( yes "r" | git mergetool submod >/dev/null 2>&1 ) &&
126     test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
127     test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
128     test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
129     git submodule update -N &&
130     test "$(cat submod/bar)" = "master submodule" &&
131     git commit -m "branch1 resolved with mergetool - autocrlf" &&
132     git config core.autocrlf false &&
133     git reset --hard
134 '
135
136 test_expect_success 'mergetool in subdir' '
137     git checkout -b test3 branch1 &&
138     git submodule update -N &&
139     (
140         cd subdir &&
141         test_must_fail git merge master >/dev/null 2>&1 &&
142         ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
143         test "$(cat file3)" = "master new sub"
144     )
145 '
146
147 test_expect_success 'mergetool on file in parent dir' '
148     (
149         cd subdir &&
150         ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
151         ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
152         ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
153         ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
154         ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
155         ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
156         test "$(cat ../file1)" = "master updated" &&
157         test "$(cat ../file2)" = "master new" &&
158         test "$(cat ../submod/bar)" = "branch1 submodule" &&
159         git commit -m "branch1 resolved with mergetool - subdir"
160     )
161 '
162
163 test_expect_success 'mergetool skips autoresolved' '
164     git checkout -b test4 branch1 &&
165     git submodule update -N &&
166     test_must_fail git merge master &&
167     test -n "$(git ls-files -u)" &&
168     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
169     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
170     ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
171     output="$(git mergetool --no-prompt)" &&
172     test "$output" = "No files need merging" &&
173     git reset --hard
174 '
175
176 test_expect_success 'mergetool merges all from subdir' '
177     (
178         cd subdir &&
179         git config rerere.enabled false &&
180         test_must_fail git merge master &&
181         ( yes "r" | git mergetool ../submod ) &&
182         ( yes "d" "d" | git mergetool --no-prompt ) &&
183         test "$(cat ../file1)" = "master updated" &&
184         test "$(cat ../file2)" = "master new" &&
185         test "$(cat file3)" = "master new sub" &&
186         ( cd .. && git submodule update -N ) &&
187         test "$(cat ../submod/bar)" = "master submodule" &&
188         git commit -m "branch2 resolved by mergetool from subdir"
189     )
190 '
191
192 test_expect_success 'mergetool skips resolved paths when rerere is active' '
193     git config rerere.enabled true &&
194     rm -rf .git/rr-cache &&
195     git checkout -b test5 branch1
196     git submodule update -N &&
197     test_must_fail git merge master >/dev/null 2>&1 &&
198     ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) &&
199     ( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) &&
200     git submodule update -N &&
201     output="$(yes "n" | git mergetool --no-prompt)" &&
202     test "$output" = "No files need merging" &&
203     git reset --hard
204 '
205
206 test_expect_success 'conflicted stash sets up rerere'  '
207     git config rerere.enabled true &&
208     git checkout stash1 &&
209     echo "Conflicting stash content" >file11 &&
210     git stash &&
211
212     git checkout --detach stash2 &&
213     test_must_fail git stash apply &&
214
215     test -n "$(git ls-files -u)" &&
216     conflicts="$(git rerere remaining)" &&
217     test "$conflicts" = "file11" &&
218     output="$(git mergetool --no-prompt)" &&
219     test "$output" != "No files need merging" &&
220
221     git commit -am "save the stash resolution" &&
222
223     git reset --hard stash2 &&
224     test_must_fail git stash apply &&
225
226     test -n "$(git ls-files -u)" &&
227     conflicts="$(git rerere remaining)" &&
228     test -z "$conflicts" &&
229     output="$(git mergetool --no-prompt)" &&
230     test "$output" = "No files need merging"
231 '
232
233 test_expect_success 'mergetool takes partial path' '
234     git reset --hard
235     git config rerere.enabled false &&
236     git checkout -b test12 branch1 &&
237     git submodule update -N &&
238     test_must_fail git merge master &&
239
240     #shouldnt need these lines
241     #( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
242     #( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
243     #( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
244     #( yes "" | git mergetool file1 file2 >/dev/null 2>&1 ) &&
245
246     ( yes "" | git mergetool subdir ) &&
247
248     test "$(cat subdir/file3)" = "master new sub" &&
249     git reset --hard
250 '
251
252 test_expect_success 'deleted vs modified submodule' '
253     git checkout -b test6 branch1 &&
254     git submodule update -N &&
255     mv submod submod-movedaside &&
256     git rm submod &&
257     git commit -m "Submodule deleted from branch" &&
258     git checkout -b test6.a test6 &&
259     test_must_fail git merge master &&
260     test -n "$(git ls-files -u)" &&
261     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
262     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
263     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
264     ( yes "r" | git mergetool submod ) &&
265     rmdir submod && mv submod-movedaside submod &&
266     test "$(cat submod/bar)" = "branch1 submodule" &&
267     git submodule update -N &&
268     test "$(cat submod/bar)" = "master submodule" &&
269     output="$(git mergetool --no-prompt)" &&
270     test "$output" = "No files need merging" &&
271     git commit -m "Merge resolved by keeping module" &&
272
273     mv submod submod-movedaside &&
274     git checkout -b test6.b test6 &&
275     git submodule update -N &&
276     test_must_fail git merge master &&
277     test -n "$(git ls-files -u)" &&
278     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
279     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
280     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
281     ( yes "l" | git mergetool submod ) &&
282     test ! -e submod &&
283     output="$(git mergetool --no-prompt)" &&
284     test "$output" = "No files need merging" &&
285     git commit -m "Merge resolved by deleting module" &&
286
287     mv submod-movedaside submod &&
288     git checkout -b test6.c master &&
289     git submodule update -N &&
290     test_must_fail git merge test6 &&
291     test -n "$(git ls-files -u)" &&
292     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
293     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
294     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
295     ( yes "r" | git mergetool submod ) &&
296     test ! -e submod &&
297     test -d submod.orig &&
298     git submodule update -N &&
299     output="$(git mergetool --no-prompt)" &&
300     test "$output" = "No files need merging" &&
301     git commit -m "Merge resolved by deleting module" &&
302     mv submod.orig submod &&
303
304     git checkout -b test6.d master &&
305     git submodule update -N &&
306     test_must_fail git merge test6 &&
307     test -n "$(git ls-files -u)" &&
308     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
309     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
310     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
311     ( yes "l" | git mergetool submod ) &&
312     test "$(cat submod/bar)" = "master submodule" &&
313     git submodule update -N &&
314     test "$(cat submod/bar)" = "master submodule" &&
315     output="$(git mergetool --no-prompt)" &&
316     test "$output" = "No files need merging" &&
317     git commit -m "Merge resolved by keeping module" &&
318     git reset --hard HEAD
319 '
320
321 test_expect_success 'file vs modified submodule' '
322     git checkout -b test7 branch1 &&
323     git submodule update -N &&
324     mv submod submod-movedaside &&
325     git rm submod &&
326     echo not a submodule >submod &&
327     git add submod &&
328     git commit -m "Submodule path becomes file" &&
329     git checkout -b test7.a branch1 &&
330     test_must_fail git merge master &&
331     test -n "$(git ls-files -u)" &&
332     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
333     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
334     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
335     ( yes "r" | git mergetool submod ) &&
336     rmdir submod && mv submod-movedaside submod &&
337     test "$(cat submod/bar)" = "branch1 submodule" &&
338     git submodule update -N &&
339     test "$(cat submod/bar)" = "master submodule" &&
340     output="$(git mergetool --no-prompt)" &&
341     test "$output" = "No files need merging" &&
342     git commit -m "Merge resolved by keeping module" &&
343
344     mv submod submod-movedaside &&
345     git checkout -b test7.b test7 &&
346     test_must_fail git merge master &&
347     test -n "$(git ls-files -u)" &&
348     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
349     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
350     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
351     ( yes "l" | git mergetool submod ) &&
352     git submodule update -N &&
353     test "$(cat submod)" = "not a submodule" &&
354     output="$(git mergetool --no-prompt)" &&
355     test "$output" = "No files need merging" &&
356     git commit -m "Merge resolved by keeping file" &&
357
358     git checkout -b test7.c master &&
359     rmdir submod && mv submod-movedaside submod &&
360     test ! -e submod.orig &&
361     git submodule update -N &&
362     test_must_fail git merge test7 &&
363     test -n "$(git ls-files -u)" &&
364     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
365     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
366     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
367     ( yes "r" | git mergetool submod ) &&
368     test -d submod.orig &&
369     git submodule update -N &&
370     test "$(cat submod)" = "not a submodule" &&
371     output="$(git mergetool --no-prompt)" &&
372     test "$output" = "No files need merging" &&
373     git commit -m "Merge resolved by keeping file" &&
374
375     git checkout -b test7.d master &&
376     rmdir submod && mv submod.orig submod &&
377     git submodule update -N &&
378     test_must_fail git merge test7 &&
379     test -n "$(git ls-files -u)" &&
380     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
381     ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
382     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
383     ( yes "l" | git mergetool submod ) &&
384     test "$(cat submod/bar)" = "master submodule" &&
385     git submodule update -N &&
386     test "$(cat submod/bar)" = "master submodule" &&
387     output="$(git mergetool --no-prompt)" &&
388     test "$output" = "No files need merging" &&
389     git commit -m "Merge resolved by keeping module"
390 '
391
392 test_expect_success 'submodule in subdirectory' '
393     git checkout -b test10 branch1 &&
394     git submodule update -N &&
395     (
396         cd subdir &&
397         test_create_repo subdir_module &&
398         (
399             cd subdir_module &&
400             : >file15 &&
401             git add file15 &&
402             git commit -m "add initial versions"
403         )
404     ) &&
405     git submodule add git://example.com/subsubmodule subdir/subdir_module &&
406     git add subdir/subdir_module &&
407     git commit -m "add submodule in subdirectory" &&
408
409     git checkout -b test10.a test10 &&
410     git submodule update -N &&
411     (
412         cd subdir/subdir_module &&
413         git checkout -b super10.a &&
414         echo test10.a >file15 &&
415         git add file15 &&
416         git commit -m "on branch 10.a"
417     ) &&
418     git add subdir/subdir_module &&
419     git commit -m "change submodule in subdirectory on test10.a" &&
420
421     git checkout -b test10.b test10 &&
422     git submodule update -N &&
423     (
424         cd subdir/subdir_module &&
425         git checkout -b super10.b &&
426         echo test10.b >file15 &&
427         git add file15 &&
428         git commit -m "on branch 10.b"
429     ) &&
430     git add subdir/subdir_module &&
431     git commit -m "change submodule in subdirectory on test10.b" &&
432
433     test_must_fail git merge test10.a >/dev/null 2>&1 &&
434     (
435         cd subdir &&
436         ( yes "l" | git mergetool subdir_module )
437     ) &&
438     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
439     git submodule update -N &&
440     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
441     git reset --hard &&
442     git submodule update -N &&
443
444     test_must_fail git merge test10.a >/dev/null 2>&1 &&
445     ( yes "r" | git mergetool subdir/subdir_module ) &&
446     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
447     git submodule update -N &&
448     test "$(cat subdir/subdir_module/file15)" = "test10.a" &&
449     git commit -m "branch1 resolved with mergetool" &&
450     rm -rf subdir/subdir_module
451 '
452
453 test_expect_success 'directory vs modified submodule' '
454     git checkout -b test11 branch1 &&
455     mv submod submod-movedaside &&
456     git rm submod &&
457     mkdir submod &&
458     echo not a submodule >submod/file16 &&
459     git add submod/file16 &&
460     git commit -m "Submodule path becomes directory" &&
461
462     test_must_fail git merge master &&
463     test -n "$(git ls-files -u)" &&
464     ( yes "l" | git mergetool submod ) &&
465     test "$(cat submod/file16)" = "not a submodule" &&
466     rm -rf submod.orig &&
467
468     git reset --hard >/dev/null 2>&1 &&
469     test_must_fail git merge master &&
470     test -n "$(git ls-files -u)" &&
471     test ! -e submod.orig &&
472     ( yes "r" | git mergetool submod ) &&
473     test -d submod.orig &&
474     test "$(cat submod.orig/file16)" = "not a submodule" &&
475     rm -r submod.orig &&
476     mv submod-movedaside/.git submod &&
477     ( cd submod && git clean -f && git reset --hard ) &&
478     git submodule update -N &&
479     test "$(cat submod/bar)" = "master submodule" &&
480     git reset --hard >/dev/null 2>&1 && rm -rf submod-movedaside &&
481
482     git checkout -b test11.c master &&
483     git submodule update -N &&
484     test_must_fail git merge test11 &&
485     test -n "$(git ls-files -u)" &&
486     ( yes "l" | git mergetool submod ) &&
487     git submodule update -N &&
488     test "$(cat submod/bar)" = "master submodule" &&
489
490     git reset --hard >/dev/null 2>&1 &&
491     git submodule update -N &&
492     test_must_fail git merge test11 &&
493     test -n "$(git ls-files -u)" &&
494     test ! -e submod.orig &&
495     ( yes "r" | git mergetool submod ) &&
496     test "$(cat submod/file16)" = "not a submodule" &&
497
498     git reset --hard master >/dev/null 2>&1 &&
499     ( cd submod && git clean -f && git reset --hard ) &&
500     git submodule update -N
501 '
502
503 test_expect_success 'file with no base' '
504     git checkout -b test13 branch1 &&
505     test_must_fail git merge master &&
506     git mergetool --no-prompt --tool mybase -- both &&
507     >expected &&
508     test_cmp both expected &&
509     git reset --hard master >/dev/null 2>&1
510 '
511
512 test_expect_success 'custom commands override built-ins' '
513     git checkout -b test14 branch1 &&
514     git config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
515     git config mergetool.defaults.trustExitCode true &&
516     test_must_fail git merge master &&
517     git mergetool --no-prompt --tool defaults -- both &&
518     echo master both added >expected &&
519     test_cmp both expected &&
520     git config --unset mergetool.defaults.cmd &&
521     git config --unset mergetool.defaults.trustExitCode &&
522     git reset --hard master >/dev/null 2>&1
523 '
524
525 test_done