]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7800-difftool.sh
Prepare for 2.9.4
[thirdparty/git.git] / t / t7800-difftool.sh
CommitLineData
f92f2038
DA
1#!/bin/sh
2#
9e5a86f2 3# Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
f92f2038
DA
4#
5
6test_description='git-difftool
7
8Testing basic diff tool invocation
9'
10
11. ./test-lib.sh
12
e42360c4 13difftool_test_setup ()
f92f2038 14{
e42360c4
DA
15 test_config diff.tool test-tool &&
16 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
17 test_config difftool.bogus-tool.cmd false
f92f2038
DA
18}
19
e42360c4 20prompt_given ()
a904392e
DA
21{
22 prompt="$1"
cce076e3 23 test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
ba959de1
SC
24}
25
f92f2038 26# Create a file on master and change it on branch
2c4f3026 27test_expect_success PERL 'setup' '
f92f2038
DA
28 echo master >file &&
29 git add file &&
30 git commit -m "added file" &&
31
32 git checkout -b branch master &&
33 echo branch >file &&
34 git commit -a -m "branch changed file" &&
35 git checkout master
36'
37
38# Configure a custom difftool.<tool>.cmd and use it
2c4f3026 39test_expect_success PERL 'custom commands' '
e42360c4
DA
40 difftool_test_setup &&
41 test_config difftool.test-tool.cmd "cat \"\$REMOTE\"" &&
42 echo master >expect &&
43 git difftool --no-prompt branch >actual &&
44 test_cmp expect actual &&
f92f2038 45
e42360c4
DA
46 test_config difftool.test-tool.cmd "cat \"\$LOCAL\"" &&
47 echo branch >expect &&
48 git difftool --no-prompt branch >actual &&
49 test_cmp expect actual
f92f2038
DA
50'
51
e42360c4 52test_expect_success PERL 'custom tool commands override built-ins' '
f469e840 53 test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" &&
e42360c4 54 echo master >expect &&
f469e840 55 git difftool --tool vimdiff --no-prompt branch >actual &&
e42360c4 56 test_cmp expect actual
a427ef7a
DA
57'
58
2c4f3026 59test_expect_success PERL 'difftool ignores bad --tool values' '
e42360c4 60 : >expect &&
89294d14 61 test_must_fail \
e42360c4
DA
62 git difftool --no-prompt --tool=bad-tool branch >actual &&
63 test_cmp expect actual
f92f2038
DA
64'
65
d50b2c73 66test_expect_success PERL 'difftool forwards arguments to diff' '
e42360c4 67 difftool_test_setup &&
d50b2c73
DA
68 >for-diff &&
69 git add for-diff &&
70 echo changes>for-diff &&
71 git add for-diff &&
e42360c4
DA
72 : >expect &&
73 git difftool --cached --no-prompt -- for-diff >actual &&
74 test_cmp expect actual &&
d50b2c73
DA
75 git reset -- for-diff &&
76 rm for-diff
77'
78
2b52123f
DA
79test_expect_success PERL 'difftool ignores exit code' '
80 test_config difftool.error.cmd false &&
81 git difftool -y -t error branch
82'
83
84test_expect_success PERL 'difftool forwards exit code with --trust-exit-code' '
85 test_config difftool.error.cmd false &&
86 test_must_fail git difftool -y --trust-exit-code -t error branch
87'
88
99474b63
DA
89test_expect_success PERL 'difftool forwards exit code with --trust-exit-code for built-ins' '
90 test_config difftool.vimdiff.path false &&
91 test_must_fail git difftool -y --trust-exit-code -t vimdiff branch
92'
93
2b52123f
DA
94test_expect_success PERL 'difftool honors difftool.trustExitCode = true' '
95 test_config difftool.error.cmd false &&
96 test_config difftool.trustExitCode true &&
97 test_must_fail git difftool -y -t error branch
98'
99
100test_expect_success PERL 'difftool honors difftool.trustExitCode = false' '
101 test_config difftool.error.cmd false &&
102 test_config difftool.trustExitCode false &&
103 git difftool -y -t error branch
104'
105
106test_expect_success PERL 'difftool ignores exit code with --no-trust-exit-code' '
107 test_config difftool.error.cmd false &&
108 test_config difftool.trustExitCode true &&
109 git difftool -y --no-trust-exit-code -t error branch
110'
111
112test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
113 test_when_finished "rm -f for-diff .git/fail-right-file" &&
114 test_when_finished "git reset -- for-diff" &&
115 write_script .git/fail-right-file <<-\EOF &&
116 echo "$2"
117 exit 1
118 EOF
119 >for-diff &&
120 git add for-diff &&
121 echo file >expect &&
122 test_must_fail git difftool -y --trust-exit-code \
123 --extcmd .git/fail-right-file branch >actual &&
124 test_cmp expect actual
125'
126
45a4f5d9
JK
127test_expect_success PERL 'difftool honors exit status if command not found' '
128 test_config difftool.nonexistent.cmd i-dont-exist &&
129 test_config difftool.trustExitCode false &&
130 test_must_fail git difftool -y -t nonexistent branch
131'
132
2c4f3026 133test_expect_success PERL 'difftool honors --gui' '
e42360c4
DA
134 difftool_test_setup &&
135 test_config merge.tool bogus-tool &&
136 test_config diff.tool bogus-tool &&
137 test_config diff.guitool test-tool &&
4cefa495 138
e42360c4
DA
139 echo branch >expect &&
140 git difftool --no-prompt --gui branch >actual &&
141 test_cmp expect actual
4cefa495
DA
142'
143
85089604 144test_expect_success PERL 'difftool --gui last setting wins' '
e42360c4
DA
145 difftool_test_setup &&
146 : >expect &&
147 git difftool --no-prompt --gui --no-gui >actual &&
148 test_cmp expect actual &&
85089604 149
e42360c4
DA
150 test_config merge.tool bogus-tool &&
151 test_config diff.tool bogus-tool &&
152 test_config diff.guitool test-tool &&
153 echo branch >expect &&
154 git difftool --no-prompt --no-gui --gui branch >actual &&
155 test_cmp expect actual
85089604
TH
156'
157
2c4f3026 158test_expect_success PERL 'difftool --gui works without configured diff.guitool' '
e42360c4
DA
159 difftool_test_setup &&
160 echo branch >expect &&
161 git difftool --no-prompt --gui branch >actual &&
162 test_cmp expect actual
42accaec
DA
163'
164
f92f2038 165# Specify the diff tool using $GIT_DIFF_TOOL
2c4f3026 166test_expect_success PERL 'GIT_DIFF_TOOL variable' '
e42360c4
DA
167 difftool_test_setup &&
168 git config --unset diff.tool &&
169 echo branch >expect &&
170 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
171 test_cmp expect actual
f92f2038
DA
172'
173
174# Test the $GIT_*_TOOL variables and ensure
175# that $GIT_DIFF_TOOL always wins unless --tool is specified
2c4f3026 176test_expect_success PERL 'GIT_DIFF_TOOL overrides' '
e42360c4
DA
177 difftool_test_setup &&
178 test_config diff.tool bogus-tool &&
179 test_config merge.tool bogus-tool &&
f92f2038 180
e42360c4
DA
181 echo branch >expect &&
182 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
183 test_cmp expect actual &&
f92f2038 184
e42360c4
DA
185 test_config diff.tool bogus-tool &&
186 test_config merge.tool bogus-tool &&
187 GIT_DIFF_TOOL=bogus-tool \
188 git difftool --no-prompt --tool=test-tool branch >actual &&
189 test_cmp expect actual
f92f2038
DA
190'
191
192# Test that we don't have to pass --no-prompt to difftool
193# when $GIT_DIFFTOOL_NO_PROMPT is true
2c4f3026 194test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' '
e42360c4
DA
195 difftool_test_setup &&
196 echo branch >expect &&
197 GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
198 test_cmp expect actual
f92f2038
DA
199'
200
a904392e
DA
201# git-difftool supports the difftool.prompt variable.
202# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
2c4f3026 203test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' '
e42360c4
DA
204 difftool_test_setup &&
205 test_config difftool.prompt false &&
206 echo >input &&
207 GIT_DIFFTOOL_PROMPT=true git difftool branch <input >output &&
208 prompt=$(tail -1 <output) &&
209 prompt_given "$prompt"
a904392e
DA
210'
211
212# Test that we don't have to pass --no-prompt when difftool.prompt is false
2c4f3026 213test_expect_success PERL 'difftool.prompt config variable is false' '
e42360c4
DA
214 difftool_test_setup &&
215 test_config difftool.prompt false &&
216 echo branch >expect &&
217 git difftool branch >actual &&
218 test_cmp expect actual
a904392e
DA
219'
220
a88183f1 221# Test that we don't have to pass --no-prompt when mergetool.prompt is false
2c4f3026 222test_expect_success PERL 'difftool merge.prompt = false' '
e42360c4 223 difftool_test_setup &&
bc0f35ca 224 test_might_fail git config --unset difftool.prompt &&
e42360c4
DA
225 test_config mergetool.prompt false &&
226 echo branch >expect &&
227 git difftool branch >actual &&
228 test_cmp expect actual
a88183f1
DA
229'
230
a904392e 231# Test that the -y flag can override difftool.prompt = true
2c4f3026 232test_expect_success PERL 'difftool.prompt can overridden with -y' '
e42360c4
DA
233 difftool_test_setup &&
234 test_config difftool.prompt true &&
235 echo branch >expect &&
236 git difftool -y branch >actual &&
237 test_cmp expect actual
a904392e
DA
238'
239
240# Test that the --prompt flag can override difftool.prompt = false
2c4f3026 241test_expect_success PERL 'difftool.prompt can overridden with --prompt' '
e42360c4
DA
242 difftool_test_setup &&
243 test_config difftool.prompt false &&
244 echo >input &&
245 git difftool --prompt branch <input >output &&
246 prompt=$(tail -1 <output) &&
247 prompt_given "$prompt"
a904392e
DA
248'
249
250# Test that the last flag passed on the command-line wins
2c4f3026 251test_expect_success PERL 'difftool last flag wins' '
e42360c4
DA
252 difftool_test_setup &&
253 echo branch >expect &&
254 git difftool --prompt --no-prompt branch >actual &&
255 test_cmp expect actual &&
256 echo >input &&
257 git difftool --no-prompt --prompt branch <input >output &&
258 prompt=$(tail -1 <output) &&
259 prompt_given "$prompt"
a904392e
DA
260'
261
f92f2038
DA
262# git-difftool falls back to git-mergetool config variables
263# so test that behavior here
2c4f3026 264test_expect_success PERL 'difftool + mergetool config variables' '
e42360c4
DA
265 test_config merge.tool test-tool &&
266 test_config mergetool.test-tool.cmd "cat \$LOCAL" &&
267 echo branch >expect &&
268 git difftool --no-prompt branch >actual &&
269 test_cmp expect actual &&
f92f2038
DA
270
271 # set merge.tool to something bogus, diff.tool to test-tool
e42360c4
DA
272 test_config merge.tool bogus-tool &&
273 test_config diff.tool test-tool &&
274 git difftool --no-prompt branch >actual &&
275 test_cmp expect actual
f92f2038
DA
276'
277
2c4f3026 278test_expect_success PERL 'difftool.<tool>.path' '
e42360c4
DA
279 test_config difftool.tkdiff.path echo &&
280 git difftool --tool=tkdiff --no-prompt branch >output &&
281 lines=$(grep file output | wc -l) &&
282 test "$lines" -eq 1
1c6f5b52
DA
283'
284
2c4f3026 285test_expect_success PERL 'difftool --extcmd=cat' '
e42360c4
DA
286 echo branch >expect &&
287 echo master >>expect &&
288 git difftool --no-prompt --extcmd=cat branch >actual &&
289 test_cmp expect actual
f47f1e2c 290'
1c6f5b52 291
2c4f3026 292test_expect_success PERL 'difftool --extcmd cat' '
e42360c4
DA
293 echo branch >expect &&
294 echo master >>expect &&
295 git difftool --no-prompt --extcmd=cat branch >actual &&
296 test_cmp expect actual
f47f1e2c 297'
1c6f5b52 298
2c4f3026 299test_expect_success PERL 'difftool -x cat' '
e42360c4
DA
300 echo branch >expect &&
301 echo master >>expect &&
302 git difftool --no-prompt -x cat branch >actual &&
303 test_cmp expect actual
9f3d54d1
DA
304'
305
2c4f3026 306test_expect_success PERL 'difftool --extcmd echo arg1' '
e42360c4
DA
307 echo file >expect &&
308 git difftool --no-prompt \
309 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
310 test_cmp expect actual
9f3d54d1 311'
1c6f5b52 312
2c4f3026 313test_expect_success PERL 'difftool --extcmd cat arg1' '
e42360c4
DA
314 echo master >expect &&
315 git difftool --no-prompt \
316 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
317 test_cmp expect actual
9f3d54d1 318'
1c6f5b52 319
2c4f3026 320test_expect_success PERL 'difftool --extcmd cat arg2' '
e42360c4
DA
321 echo branch >expect &&
322 git difftool --no-prompt \
323 --extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
324 test_cmp expect actual
f92f2038
DA
325'
326
ba959de1
SC
327# Create a second file on master and a different version on branch
328test_expect_success PERL 'setup with 2 files different' '
329 echo m2 >file2 &&
330 git add file2 &&
331 git commit -m "added file2" &&
332
333 git checkout branch &&
334 echo br2 >file2 &&
335 git add file2 &&
336 git commit -a -m "branch changed file2" &&
337 git checkout master
338'
339
340test_expect_success PERL 'say no to the first file' '
e42360c4
DA
341 (echo n && echo) >input &&
342 git difftool -x cat branch <input >output &&
472353a5
JK
343 grep m2 output &&
344 grep br2 output &&
345 ! grep master output &&
346 ! grep branch output
ba959de1
SC
347'
348
349test_expect_success PERL 'say no to the second file' '
e42360c4
DA
350 (echo && echo n) >input &&
351 git difftool -x cat branch <input >output &&
472353a5
JK
352 grep master output &&
353 grep branch output &&
354 ! grep m2 output &&
355 ! grep br2 output
ba959de1
SC
356'
357
25098690
JS
358test_expect_success PERL 'ending prompt input with EOF' '
359 git difftool -x cat branch </dev/null >output &&
360 ! grep master output &&
361 ! grep branch output &&
362 ! grep m2 output &&
363 ! grep br2 output
364'
365
bf73fc21 366test_expect_success PERL 'difftool --tool-help' '
e42360c4 367 git difftool --tool-help >output &&
472353a5 368 grep tool output
bf73fc21
TH
369'
370
7e0abcec
TH
371test_expect_success PERL 'setup change in subdirectory' '
372 git checkout master &&
373 mkdir sub &&
374 echo master >sub/sub &&
375 git add sub/sub &&
376 git commit -m "added sub/sub" &&
377 echo test >>file &&
378 echo test >>sub/sub &&
3caf5a93 379 git add file sub/sub &&
7e0abcec
TH
380 git commit -m "modified both"
381'
382
e01afdb7
JK
383run_dir_diff_test () {
384 test_expect_success PERL "$1 --no-symlinks" "
385 symlinks=--no-symlinks &&
386 $2
387 "
388 test_expect_success PERL,SYMLINKS "$1 --symlinks" "
389 symlinks=--symlinks &&
390 $2
391 "
392}
393
394run_dir_diff_test 'difftool -d' '
395 git difftool -d $symlinks --extcmd ls branch >output &&
472353a5
JK
396 grep sub output &&
397 grep file output
7e0abcec
TH
398'
399
e01afdb7
JK
400run_dir_diff_test 'difftool --dir-diff' '
401 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
472353a5
JK
402 grep sub output &&
403 grep file output
7e0abcec
TH
404'
405
e01afdb7
JK
406run_dir_diff_test 'difftool --dir-diff ignores --prompt' '
407 git difftool --dir-diff $symlinks --prompt --extcmd ls branch >output &&
472353a5
JK
408 grep sub output &&
409 grep file output
bf341b90
JK
410'
411
e01afdb7 412run_dir_diff_test 'difftool --dir-diff from subdirectory' '
bf341b90
JK
413 (
414 cd sub &&
e01afdb7 415 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
472353a5
JK
416 grep sub output &&
417 grep file output
bf341b90
JK
418 )
419'
420
98f917ed
DA
421run_dir_diff_test 'difftool --dir-diff from subdirectory with GIT_DIR set' '
422 (
423 GIT_DIR=$(pwd)/.git &&
424 export GIT_DIR &&
425 GIT_WORK_TREE=$(pwd) &&
426 export GIT_WORK_TREE &&
427 cd sub &&
428 git difftool --dir-diff $symlinks --extcmd ls \
429 branch -- sub >output &&
430 grep sub output &&
431 ! grep file output
432 )
433'
434
1f197a1d
JK
435run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
436 test_when_finished git reset --hard &&
437 rm file2 &&
438 git difftool --dir-diff $symlinks --extcmd ls branch master >output &&
439 grep file2 output
440'
441
366f9cea
DA
442run_dir_diff_test 'difftool --dir-diff with unmerged files' '
443 test_when_finished git reset --hard &&
444 test_config difftool.echo.cmd "echo ok" &&
445 git checkout -B conflict-a &&
446 git checkout -B conflict-b &&
447 git checkout conflict-a &&
448 echo a >>file &&
449 git add file &&
450 git commit -m conflict-a &&
451 git checkout conflict-b &&
452 echo b >>file &&
453 git add file &&
454 git commit -m conflict-b &&
455 git checkout master &&
456 git merge conflict-a &&
457 test_must_fail git merge conflict-b &&
458 cat >expect <<-EOF &&
459 ok
460 EOF
461 git difftool --dir-diff $symlinks -t echo >actual &&
462 test_cmp expect actual
463'
464
02c56314
JK
465write_script .git/CHECK_SYMLINKS <<\EOF
466for f in file file2 sub/sub
467do
468 echo "$f"
d2addc3b 469 ls -ld "$2/$f" | sed -e 's/.* -> //'
02c56314
JK
470done >actual
471EOF
472
473test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' '
474 cat >expect <<-EOF &&
475 file
fd318a94 476 $PWD/file
02c56314 477 file2
fd318a94 478 $PWD/file2
02c56314 479 sub/sub
fd318a94 480 $PWD/sub/sub
02c56314
JK
481 EOF
482 git difftool --dir-diff --symlink \
483 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
484 test_cmp actual expect
485'
486
32eaf1de
KS
487write_script modify-right-file <<\EOF
488echo "new content" >"$2/file"
489EOF
490
491run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
492 test_when_finished git reset --hard &&
493 echo "orig content" >file &&
fd318a94 494 git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
32eaf1de
KS
495 echo "new content" >expect &&
496 test_cmp expect file
497'
498
499run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
500 test_when_finished git reset --hard &&
fd318a94 501 git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
32eaf1de
KS
502 echo "new content" >expect &&
503 test_cmp expect file
504'
505
67aa147a
JK
506write_script modify-file <<\EOF
507echo "new content" >file
508EOF
509
510test_expect_success PERL 'difftool --no-symlinks does not overwrite working tree file ' '
511 echo "orig content" >file &&
fd318a94 512 git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-file" branch &&
67aa147a
JK
513 echo "new content" >expect &&
514 test_cmp expect file
515'
516
517write_script modify-both-files <<\EOF
518echo "wt content" >file &&
519echo "tmp content" >"$2/file" &&
520echo "$2" >tmpdir
521EOF
522
523test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
524 (
525 TMPDIR=$TRASH_DIRECTORY &&
526 export TMPDIR &&
527 echo "orig content" >file &&
fd318a94 528 test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-both-files" branch &&
67aa147a
JK
529 echo "wt content" >expect &&
530 test_cmp expect file &&
531 echo "tmp content" >expect &&
532 test_cmp expect "$(cat tmpdir)/file"
533 )
534'
535
fcfec8bd
JH
536test_expect_success PERL 'difftool properly honors gitlink and core.worktree' '
537 git submodule add ./. submod/ule &&
da568b66
JK
538 test_config -C submod/ule diff.tool checktrees &&
539 test_config -C submod/ule difftool.checktrees.cmd '\''
540 test -d "$LOCAL" && test -d "$REMOTE" && echo good
541 '\'' &&
fcfec8bd
JH
542 (
543 cd submod/ule &&
fcfec8bd
JH
544 echo good >expect &&
545 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
546 test_cmp expect actual
547 )
548'
549
cfe2d4be
DA
550test_expect_success PERL,SYMLINKS 'difftool --dir-diff symlinked directories' '
551 git init dirlinks &&
552 (
553 cd dirlinks &&
554 git config diff.tool checktrees &&
555 git config difftool.checktrees.cmd "echo good" &&
556 mkdir foo &&
557 : >foo/bar &&
558 git add foo/bar &&
559 test_commit symlink-one &&
560 ln -s foo link &&
561 git add link &&
562 test_commit symlink-two &&
563 echo good >expect &&
564 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
565 test_cmp expect actual
566 )
567'
568
f92f2038 569test_done