Sync with 2.6.1
[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         test_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         test_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         test_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         test_config rerere.enabled false &&
178         (
179                 cd subdir &&
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         test_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         test_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         test_config rerere.enabled false &&
236         git checkout -b test12 branch1 &&
237         git submodule update -N &&
238         test_must_fail git merge master &&
239
240         ( yes "" | git mergetool subdir ) &&
241
242         test "$(cat subdir/file3)" = "master new sub" &&
243         git reset --hard
244 '
245
246 test_expect_success 'deleted vs modified submodule' '
247         git checkout -b test6 branch1 &&
248         git submodule update -N &&
249         mv submod submod-movedaside &&
250         git rm --cached submod &&
251         git commit -m "Submodule deleted from branch" &&
252         git checkout -b test6.a test6 &&
253         test_must_fail git merge master &&
254         test -n "$(git ls-files -u)" &&
255         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
256         ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
257         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
258         ( yes "r" | git mergetool submod ) &&
259         rmdir submod && mv submod-movedaside submod &&
260         test "$(cat submod/bar)" = "branch1 submodule" &&
261         git submodule update -N &&
262         test "$(cat submod/bar)" = "master submodule" &&
263         output="$(git mergetool --no-prompt)" &&
264         test "$output" = "No files need merging" &&
265         git commit -m "Merge resolved by keeping module" &&
266
267         mv submod submod-movedaside &&
268         git checkout -b test6.b test6 &&
269         git submodule update -N &&
270         test_must_fail git merge master &&
271         test -n "$(git ls-files -u)" &&
272         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
273         ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
274         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
275         ( yes "l" | git mergetool submod ) &&
276         test ! -e submod &&
277         output="$(git mergetool --no-prompt)" &&
278         test "$output" = "No files need merging" &&
279         git commit -m "Merge resolved by deleting module" &&
280
281         mv submod-movedaside submod &&
282         git checkout -b test6.c master &&
283         git submodule update -N &&
284         test_must_fail git merge test6 &&
285         test -n "$(git ls-files -u)" &&
286         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
287         ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
288         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
289         ( yes "r" | git mergetool submod ) &&
290         test ! -e submod &&
291         test -d submod.orig &&
292         git submodule update -N &&
293         output="$(git mergetool --no-prompt)" &&
294         test "$output" = "No files need merging" &&
295         git commit -m "Merge resolved by deleting module" &&
296         mv submod.orig submod &&
297
298         git checkout -b test6.d master &&
299         git submodule update -N &&
300         test_must_fail git merge test6 &&
301         test -n "$(git ls-files -u)" &&
302         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
303         ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
304         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
305         ( yes "l" | git mergetool submod ) &&
306         test "$(cat submod/bar)" = "master submodule" &&
307         git submodule update -N &&
308         test "$(cat submod/bar)" = "master submodule" &&
309         output="$(git mergetool --no-prompt)" &&
310         test "$output" = "No files need merging" &&
311         git commit -m "Merge resolved by keeping module" &&
312         git reset --hard HEAD
313 '
314
315 test_expect_success 'file vs modified submodule' '
316         git checkout -b test7 branch1 &&
317         git submodule update -N &&
318         mv submod submod-movedaside &&
319         git rm --cached submod &&
320         echo not a submodule >submod &&
321         git add submod &&
322         git commit -m "Submodule path becomes file" &&
323         git checkout -b test7.a branch1 &&
324         test_must_fail git merge master &&
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         rmdir submod && mv submod-movedaside submod &&
331         test "$(cat submod/bar)" = "branch1 submodule" &&
332         git submodule update -N &&
333         test "$(cat submod/bar)" = "master submodule" &&
334         output="$(git mergetool --no-prompt)" &&
335         test "$output" = "No files need merging" &&
336         git commit -m "Merge resolved by keeping module" &&
337
338         mv submod submod-movedaside &&
339         git checkout -b test7.b test7 &&
340         test_must_fail git merge master &&
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         git submodule update -N &&
347         test "$(cat submod)" = "not a submodule" &&
348         output="$(git mergetool --no-prompt)" &&
349         test "$output" = "No files need merging" &&
350         git commit -m "Merge resolved by keeping file" &&
351
352         git checkout -b test7.c master &&
353         rmdir submod && mv submod-movedaside submod &&
354         test ! -e submod.orig &&
355         git submodule update -N &&
356         test_must_fail git merge test7 &&
357         test -n "$(git ls-files -u)" &&
358         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
359         ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
360         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
361         ( yes "r" | git mergetool submod ) &&
362         test -d submod.orig &&
363         git submodule update -N &&
364         test "$(cat submod)" = "not a submodule" &&
365         output="$(git mergetool --no-prompt)" &&
366         test "$output" = "No files need merging" &&
367         git commit -m "Merge resolved by keeping file" &&
368
369         git checkout -b test7.d master &&
370         rmdir submod && mv submod.orig submod &&
371         git submodule update -N &&
372         test_must_fail git merge test7 &&
373         test -n "$(git ls-files -u)" &&
374         ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
375         ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
376         ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
377         ( yes "l" | git mergetool submod ) &&
378         test "$(cat submod/bar)" = "master submodule" &&
379         git submodule update -N &&
380         test "$(cat submod/bar)" = "master submodule" &&
381         output="$(git mergetool --no-prompt)" &&
382         test "$output" = "No files need merging" &&
383         git commit -m "Merge resolved by keeping module"
384 '
385
386 test_expect_success 'submodule in subdirectory' '
387         git checkout -b test10 branch1 &&
388         git submodule update -N &&
389         (
390                 cd subdir &&
391                 test_create_repo subdir_module &&
392                 (
393                 cd subdir_module &&
394                 : >file15 &&
395                 git add file15 &&
396                 git commit -m "add initial versions"
397                 )
398         ) &&
399         git submodule add git://example.com/subsubmodule subdir/subdir_module &&
400         git add subdir/subdir_module &&
401         git commit -m "add submodule in subdirectory" &&
402
403         git checkout -b test10.a test10 &&
404         git submodule update -N &&
405         (
406         cd subdir/subdir_module &&
407                 git checkout -b super10.a &&
408                 echo test10.a >file15 &&
409                 git add file15 &&
410                 git commit -m "on branch 10.a"
411         ) &&
412         git add subdir/subdir_module &&
413         git commit -m "change submodule in subdirectory on test10.a" &&
414
415         git checkout -b test10.b test10 &&
416         git submodule update -N &&
417         (
418                 cd subdir/subdir_module &&
419                 git checkout -b super10.b &&
420                 echo test10.b >file15 &&
421                 git add file15 &&
422                 git commit -m "on branch 10.b"
423         ) &&
424         git add subdir/subdir_module &&
425         git commit -m "change submodule in subdirectory on test10.b" &&
426
427         test_must_fail git merge test10.a >/dev/null 2>&1 &&
428         (
429                 cd subdir &&
430                 ( yes "l" | git mergetool subdir_module )
431         ) &&
432         test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
433         git submodule update -N &&
434         test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
435         git reset --hard &&
436         git submodule update -N &&
437
438         test_must_fail git merge test10.a >/dev/null 2>&1 &&
439         ( yes "r" | git mergetool subdir/subdir_module ) &&
440         test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
441         git submodule update -N &&
442         test "$(cat subdir/subdir_module/file15)" = "test10.a" &&
443         git commit -m "branch1 resolved with mergetool" &&
444         rm -rf subdir/subdir_module
445 '
446
447 test_expect_success 'directory vs modified submodule' '
448         git checkout -b test11 branch1 &&
449         mv submod submod-movedaside &&
450         git rm --cached submod &&
451         mkdir submod &&
452         echo not a submodule >submod/file16 &&
453         git add submod/file16 &&
454         git commit -m "Submodule path becomes directory" &&
455
456         test_must_fail git merge master &&
457         test -n "$(git ls-files -u)" &&
458         ( yes "l" | git mergetool submod ) &&
459         test "$(cat submod/file16)" = "not a submodule" &&
460         rm -rf submod.orig &&
461
462         git reset --hard >/dev/null 2>&1 &&
463         test_must_fail git merge master &&
464         test -n "$(git ls-files -u)" &&
465         test ! -e submod.orig &&
466         ( yes "r" | git mergetool submod ) &&
467         test -d submod.orig &&
468         test "$(cat submod.orig/file16)" = "not a submodule" &&
469         rm -r submod.orig &&
470         mv submod-movedaside/.git submod &&
471         ( cd submod && git clean -f && git reset --hard ) &&
472         git submodule update -N &&
473         test "$(cat submod/bar)" = "master submodule" &&
474         git reset --hard >/dev/null 2>&1 && rm -rf submod-movedaside &&
475
476         git checkout -b test11.c master &&
477         git submodule update -N &&
478         test_must_fail git merge test11 &&
479         test -n "$(git ls-files -u)" &&
480         ( yes "l" | git mergetool submod ) &&
481         git submodule update -N &&
482         test "$(cat submod/bar)" = "master submodule" &&
483
484         git reset --hard >/dev/null 2>&1 &&
485         git submodule update -N &&
486         test_must_fail git merge test11 &&
487         test -n "$(git ls-files -u)" &&
488         test ! -e submod.orig &&
489         ( yes "r" | git mergetool submod ) &&
490         test "$(cat submod/file16)" = "not a submodule" &&
491
492         git reset --hard master >/dev/null 2>&1 &&
493         ( cd submod && git clean -f && git reset --hard ) &&
494         git submodule update -N
495 '
496
497 test_expect_success 'file with no base' '
498         git checkout -b test13 branch1 &&
499         test_must_fail git merge master &&
500         git mergetool --no-prompt --tool mybase -- both &&
501         >expected &&
502         test_cmp both expected &&
503         git reset --hard master >/dev/null 2>&1
504 '
505
506 test_expect_success 'custom commands override built-ins' '
507         git checkout -b test14 branch1 &&
508         test_config mergetool.defaults.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
509         test_config mergetool.defaults.trustExitCode true &&
510         test_must_fail git merge master &&
511         git mergetool --no-prompt --tool defaults -- both &&
512         echo master both added >expected &&
513         test_cmp both expected &&
514         git reset --hard master >/dev/null 2>&1
515 '
516
517 test_expect_success 'filenames seen by tools start with ./' '
518         git checkout -b test15 branch1 &&
519         test_config mergetool.writeToTemp false &&
520         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
521         test_config mergetool.myecho.trustExitCode true &&
522         test_must_fail git merge master &&
523         git mergetool --no-prompt --tool myecho -- both >actual &&
524         grep ^\./both_LOCAL_ actual >/dev/null &&
525         git reset --hard master >/dev/null 2>&1
526 '
527
528 test_expect_success 'temporary filenames are used with mergetool.writeToTemp' '
529         git checkout -b test16 branch1 &&
530         test_config mergetool.writeToTemp true &&
531         test_config mergetool.myecho.cmd "echo \"\$LOCAL\"" &&
532         test_config mergetool.myecho.trustExitCode true &&
533         test_must_fail git merge master &&
534         git mergetool --no-prompt --tool myecho -- both >actual &&
535         test_must_fail grep ^\./both_LOCAL_ actual >/dev/null &&
536         grep /both_LOCAL_ actual >/dev/null &&
537         git reset --hard master >/dev/null 2>&1
538 '
539
540 test_done