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