Merge branch 'nd/maint-verify-objects' into maint
[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 master &&
59     git submodule update -N &&
60     echo master updated >file1 &&
61     echo master new >file2 &&
62     echo master updated spaced >"spaced name" &&
63     echo master both added >both &&
64     echo master updated file12 >file12 &&
65     echo master updated file14 >file14 &&
66     echo master new sub >subdir/file3 &&
67     (
68         cd submod &&
69         echo master submodule >bar &&
70         git add bar &&
71         git commit -m "Add bar on master" &&
72         git checkout -b submod-master
73     ) &&
74     git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
75     git add both &&
76     git rm file11 &&
77     git commit -m "master updates" &&
78
79     git config merge.tool mytool &&
80     git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
81     git config mergetool.mytool.trustExitCode true &&
82     git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
83     git config mergetool.mybase.trustExitCode true
84 '
85
86 test_expect_success 'custom mergetool' '
87     git checkout -b test1 branch1 &&
88     git submodule update -N &&
89     test_must_fail git merge master >/dev/null 2>&1 &&
90     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
91     ( yes "" | git mergetool file1 file1 ) &&
92     ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
93     ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
94     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
95     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
96     ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
97     test "$(cat file1)" = "master updated" &&
98     test "$(cat file2)" = "master new" &&
99     test "$(cat subdir/file3)" = "master new sub" &&
100     test "$(cat submod/bar)" = "branch1 submodule" &&
101     git commit -m "branch1 resolved with mergetool"
102 '
103
104 test_expect_success 'mergetool crlf' '
105     git config core.autocrlf true &&
106     git checkout -b test2 branch1 &&
107     test_must_fail git merge master >/dev/null 2>&1 &&
108     ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
109     ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
110     ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
111     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
112     ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
113     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
114     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
115     ( yes "r" | git mergetool submod >/dev/null 2>&1 ) &&
116     test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
117     test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
118     test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
119     git submodule update -N &&
120     test "$(cat submod/bar)" = "master submodule" &&
121     git commit -m "branch1 resolved with mergetool - autocrlf" &&
122     git config core.autocrlf false &&
123     git reset --hard
124 '
125
126 test_expect_success 'mergetool in subdir' '
127     git checkout -b test3 branch1 &&
128     git submodule update -N &&
129     (
130         cd subdir &&
131         test_must_fail git merge master >/dev/null 2>&1 &&
132         ( yes "" | git mergetool file3 >/dev/null 2>&1 ) &&
133         test "$(cat file3)" = "master new sub"
134     )
135 '
136
137 test_expect_success 'mergetool on file in parent dir' '
138     (
139         cd subdir &&
140         ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
141         ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
142         ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
143         ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
144         ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
145         ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
146         test "$(cat ../file1)" = "master updated" &&
147         test "$(cat ../file2)" = "master new" &&
148         test "$(cat ../submod/bar)" = "branch1 submodule" &&
149         git commit -m "branch1 resolved with mergetool - subdir"
150     )
151 '
152
153 test_expect_success 'mergetool skips autoresolved' '
154     git checkout -b test4 branch1 &&
155     git submodule update -N &&
156     test_must_fail git merge master &&
157     test -n "$(git ls-files -u)" &&
158     ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
159     ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
160     ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
161     output="$(git mergetool --no-prompt)" &&
162     test "$output" = "No files need merging" &&
163     git reset --hard
164 '
165
166 test_expect_success 'mergetool merges all from subdir' '
167     (
168         cd subdir &&
169         git config rerere.enabled false &&
170         test_must_fail git merge master &&
171         ( yes "r" | git mergetool ../submod ) &&
172         ( yes "d" "d" | git mergetool --no-prompt ) &&
173         test "$(cat ../file1)" = "master updated" &&
174         test "$(cat ../file2)" = "master new" &&
175         test "$(cat file3)" = "master new sub" &&
176         ( cd .. && git submodule update -N ) &&
177         test "$(cat ../submod/bar)" = "master submodule" &&
178         git commit -m "branch2 resolved by mergetool from subdir"
179     )
180 '
181
182 test_expect_success 'mergetool skips resolved paths when rerere is active' '
183     git config rerere.enabled true &&
184     rm -rf .git/rr-cache &&
185     git checkout -b test5 branch1
186     git submodule update -N &&
187     test_must_fail git merge master >/dev/null 2>&1 &&
188     ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) &&
189     ( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) &&
190     git submodule update -N &&
191     output="$(yes "n" | git mergetool --no-prompt)" &&
192     test "$output" = "No files need merging" &&
193     git reset --hard
194 '
195
196 test_expect_success 'mergetool takes partial path' '
197     git config rerere.enabled false &&
198     git checkout -b test12 branch1 &&
199     git submodule update -N &&
200     test_must_fail git merge master &&
201
202     #shouldnt need these lines
203     #( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
204     #( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
205     #( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
206     #( yes "" | git mergetool file1 file2 >/dev/null 2>&1 ) &&
207
208     ( yes "" | git mergetool subdir ) &&
209
210     test "$(cat subdir/file3)" = "master new sub" &&
211     git reset --hard
212 '
213
214 test_expect_success 'deleted vs modified submodule' '
215     git checkout -b test6 branch1 &&
216     git submodule update -N &&
217     mv submod submod-movedaside &&
218     git rm submod &&
219     git commit -m "Submodule deleted from branch" &&
220     git checkout -b test6.a test6 &&
221     test_must_fail git merge master &&
222     test -n "$(git ls-files -u)" &&
223     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
224     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
225     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
226     ( yes "r" | git mergetool submod ) &&
227     rmdir submod && mv submod-movedaside submod &&
228     test "$(cat submod/bar)" = "branch1 submodule" &&
229     git submodule update -N &&
230     test "$(cat submod/bar)" = "master submodule" &&
231     output="$(git mergetool --no-prompt)" &&
232     test "$output" = "No files need merging" &&
233     git commit -m "Merge resolved by keeping module" &&
234
235     mv submod submod-movedaside &&
236     git checkout -b test6.b test6 &&
237     git submodule update -N &&
238     test_must_fail git merge master &&
239     test -n "$(git ls-files -u)" &&
240     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
241     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
242     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
243     ( yes "l" | git mergetool submod ) &&
244     test ! -e submod &&
245     output="$(git mergetool --no-prompt)" &&
246     test "$output" = "No files need merging" &&
247     git commit -m "Merge resolved by deleting module" &&
248
249     mv submod-movedaside submod &&
250     git checkout -b test6.c master &&
251     git submodule update -N &&
252     test_must_fail git merge test6 &&
253     test -n "$(git ls-files -u)" &&
254     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
255     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
256     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
257     ( yes "r" | git mergetool submod ) &&
258     test ! -e submod &&
259     test -d submod.orig &&
260     git submodule update -N &&
261     output="$(git mergetool --no-prompt)" &&
262     test "$output" = "No files need merging" &&
263     git commit -m "Merge resolved by deleting module" &&
264     mv submod.orig submod &&
265
266     git checkout -b test6.d master &&
267     git submodule update -N &&
268     test_must_fail git merge test6 &&
269     test -n "$(git ls-files -u)" &&
270     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
271     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
272     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
273     ( yes "l" | git mergetool submod ) &&
274     test "$(cat submod/bar)" = "master submodule" &&
275     git submodule update -N &&
276     test "$(cat submod/bar)" = "master submodule" &&
277     output="$(git mergetool --no-prompt)" &&
278     test "$output" = "No files need merging" &&
279     git commit -m "Merge resolved by keeping module" &&
280     git reset --hard HEAD
281 '
282
283 test_expect_success 'file vs modified submodule' '
284     git checkout -b test7 branch1 &&
285     git submodule update -N &&
286     mv submod submod-movedaside &&
287     git rm submod &&
288     echo not a submodule >submod &&
289     git add submod &&
290     git commit -m "Submodule path becomes file" &&
291     git checkout -b test7.a branch1 &&
292     test_must_fail git merge master &&
293     test -n "$(git ls-files -u)" &&
294     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
295     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
296     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
297     ( yes "r" | git mergetool submod ) &&
298     rmdir submod && mv submod-movedaside submod &&
299     test "$(cat submod/bar)" = "branch1 submodule" &&
300     git submodule update -N &&
301     test "$(cat submod/bar)" = "master submodule" &&
302     output="$(git mergetool --no-prompt)" &&
303     test "$output" = "No files need merging" &&
304     git commit -m "Merge resolved by keeping module" &&
305
306     mv submod submod-movedaside &&
307     git checkout -b test7.b test7 &&
308     test_must_fail git merge master &&
309     test -n "$(git ls-files -u)" &&
310     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
311     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
312     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
313     ( yes "l" | git mergetool submod ) &&
314     git submodule update -N &&
315     test "$(cat submod)" = "not a submodule" &&
316     output="$(git mergetool --no-prompt)" &&
317     test "$output" = "No files need merging" &&
318     git commit -m "Merge resolved by keeping file" &&
319
320     git checkout -b test7.c master &&
321     rmdir submod && mv submod-movedaside submod &&
322     test ! -e submod.orig &&
323     git submodule update -N &&
324     test_must_fail git merge test7 &&
325     test -n "$(git ls-files -u)" &&
326     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
327     ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
328     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
329     ( yes "r" | git mergetool submod ) &&
330     test -d submod.orig &&
331     git submodule update -N &&
332     test "$(cat submod)" = "not a submodule" &&
333     output="$(git mergetool --no-prompt)" &&
334     test "$output" = "No files need merging" &&
335     git commit -m "Merge resolved by keeping file" &&
336
337     git checkout -b test7.d master &&
338     rmdir submod && mv submod.orig submod &&
339     git submodule update -N &&
340     test_must_fail git merge test7 &&
341     test -n "$(git ls-files -u)" &&
342     ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
343     ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
344     ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
345     ( yes "l" | git mergetool submod ) &&
346     test "$(cat submod/bar)" = "master submodule" &&
347     git submodule update -N &&
348     test "$(cat submod/bar)" = "master submodule" &&
349     output="$(git mergetool --no-prompt)" &&
350     test "$output" = "No files need merging" &&
351     git commit -m "Merge resolved by keeping module"
352 '
353
354 test_expect_success 'submodule in subdirectory' '
355     git checkout -b test10 branch1 &&
356     git submodule update -N &&
357     (
358         cd subdir &&
359         test_create_repo subdir_module &&
360         (
361             cd subdir_module &&
362             : >file15 &&
363             git add file15 &&
364             git commit -m "add initial versions"
365         )
366     ) &&
367     git submodule add git://example.com/subsubmodule subdir/subdir_module &&
368     git add subdir/subdir_module &&
369     git commit -m "add submodule in subdirectory" &&
370
371     git checkout -b test10.a test10 &&
372     git submodule update -N &&
373     (
374         cd subdir/subdir_module &&
375         git checkout -b super10.a &&
376         echo test10.a >file15 &&
377         git add file15 &&
378         git commit -m "on branch 10.a"
379     ) &&
380     git add subdir/subdir_module &&
381     git commit -m "change submodule in subdirectory on test10.a" &&
382
383     git checkout -b test10.b test10 &&
384     git submodule update -N &&
385     (
386         cd subdir/subdir_module &&
387         git checkout -b super10.b &&
388         echo test10.b >file15 &&
389         git add file15 &&
390         git commit -m "on branch 10.b"
391     ) &&
392     git add subdir/subdir_module &&
393     git commit -m "change submodule in subdirectory on test10.b" &&
394
395     test_must_fail git merge test10.a >/dev/null 2>&1 &&
396     (
397         cd subdir &&
398         ( yes "l" | git mergetool subdir_module )
399     ) &&
400     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
401     git submodule update -N &&
402     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
403     git reset --hard &&
404     git submodule update -N &&
405
406     test_must_fail git merge test10.a >/dev/null 2>&1 &&
407     ( yes "r" | git mergetool subdir/subdir_module ) &&
408     test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
409     git submodule update -N &&
410     test "$(cat subdir/subdir_module/file15)" = "test10.a" &&
411     git commit -m "branch1 resolved with mergetool" &&
412     rm -rf subdir/subdir_module
413 '
414
415 test_expect_success 'directory vs modified submodule' '
416     git checkout -b test11 branch1 &&
417     mv submod submod-movedaside &&
418     git rm submod &&
419     mkdir submod &&
420     echo not a submodule >submod/file16 &&
421     git add submod/file16 &&
422     git commit -m "Submodule path becomes directory" &&
423
424     test_must_fail git merge master &&
425     test -n "$(git ls-files -u)" &&
426     ( yes "l" | git mergetool submod ) &&
427     test "$(cat submod/file16)" = "not a submodule" &&
428     rm -rf submod.orig &&
429
430     git reset --hard >/dev/null 2>&1 &&
431     test_must_fail git merge master &&
432     test -n "$(git ls-files -u)" &&
433     test ! -e submod.orig &&
434     ( yes "r" | git mergetool submod ) &&
435     test -d submod.orig &&
436     test "$(cat submod.orig/file16)" = "not a submodule" &&
437     rm -r submod.orig &&
438     mv submod-movedaside/.git submod &&
439     ( cd submod && git clean -f && git reset --hard ) &&
440     git submodule update -N &&
441     test "$(cat submod/bar)" = "master submodule" &&
442     git reset --hard >/dev/null 2>&1 && rm -rf submod-movedaside &&
443
444     git checkout -b test11.c master &&
445     git submodule update -N &&
446     test_must_fail git merge test11 &&
447     test -n "$(git ls-files -u)" &&
448     ( yes "l" | git mergetool submod ) &&
449     git submodule update -N &&
450     test "$(cat submod/bar)" = "master submodule" &&
451
452     git reset --hard >/dev/null 2>&1 &&
453     git submodule update -N &&
454     test_must_fail git merge test11 &&
455     test -n "$(git ls-files -u)" &&
456     test ! -e submod.orig &&
457     ( yes "r" | git mergetool submod ) &&
458     test "$(cat submod/file16)" = "not a submodule" &&
459
460     git reset --hard master >/dev/null 2>&1 &&
461     ( cd submod && git clean -f && git reset --hard ) &&
462     git submodule update -N
463 '
464
465 test_expect_success 'file with no base' '
466     git checkout -b test13 branch1 &&
467     test_must_fail git merge master &&
468     git mergetool --no-prompt --tool mybase -- both &&
469     >expected &&
470     test_cmp both expected &&
471     git reset --hard master >/dev/null 2>&1
472 '
473
474 test_done