]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7800-difftool.sh
difftool: add support for --trust-exit-code
[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"
ba959de1
SC
23 test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
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
89test_expect_success PERL 'difftool honors difftool.trustExitCode = true' '
90 test_config difftool.error.cmd false &&
91 test_config difftool.trustExitCode true &&
92 test_must_fail git difftool -y -t error branch
93'
94
95test_expect_success PERL 'difftool honors difftool.trustExitCode = false' '
96 test_config difftool.error.cmd false &&
97 test_config difftool.trustExitCode false &&
98 git difftool -y -t error branch
99'
100
101test_expect_success PERL 'difftool ignores exit code with --no-trust-exit-code' '
102 test_config difftool.error.cmd false &&
103 test_config difftool.trustExitCode true &&
104 git difftool -y --no-trust-exit-code -t error branch
105'
106
107test_expect_success PERL 'difftool stops on error with --trust-exit-code' '
108 test_when_finished "rm -f for-diff .git/fail-right-file" &&
109 test_when_finished "git reset -- for-diff" &&
110 write_script .git/fail-right-file <<-\EOF &&
111 echo "$2"
112 exit 1
113 EOF
114 >for-diff &&
115 git add for-diff &&
116 echo file >expect &&
117 test_must_fail git difftool -y --trust-exit-code \
118 --extcmd .git/fail-right-file branch >actual &&
119 test_cmp expect actual
120'
121
2c4f3026 122test_expect_success PERL 'difftool honors --gui' '
e42360c4
DA
123 difftool_test_setup &&
124 test_config merge.tool bogus-tool &&
125 test_config diff.tool bogus-tool &&
126 test_config diff.guitool test-tool &&
4cefa495 127
e42360c4
DA
128 echo branch >expect &&
129 git difftool --no-prompt --gui branch >actual &&
130 test_cmp expect actual
4cefa495
DA
131'
132
85089604 133test_expect_success PERL 'difftool --gui last setting wins' '
e42360c4
DA
134 difftool_test_setup &&
135 : >expect &&
136 git difftool --no-prompt --gui --no-gui >actual &&
137 test_cmp expect actual &&
85089604 138
e42360c4
DA
139 test_config merge.tool bogus-tool &&
140 test_config diff.tool bogus-tool &&
141 test_config diff.guitool test-tool &&
142 echo branch >expect &&
143 git difftool --no-prompt --no-gui --gui branch >actual &&
144 test_cmp expect actual
85089604
TH
145'
146
2c4f3026 147test_expect_success PERL 'difftool --gui works without configured diff.guitool' '
e42360c4
DA
148 difftool_test_setup &&
149 echo branch >expect &&
150 git difftool --no-prompt --gui branch >actual &&
151 test_cmp expect actual
42accaec
DA
152'
153
f92f2038 154# Specify the diff tool using $GIT_DIFF_TOOL
2c4f3026 155test_expect_success PERL 'GIT_DIFF_TOOL variable' '
e42360c4
DA
156 difftool_test_setup &&
157 git config --unset diff.tool &&
158 echo branch >expect &&
159 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
160 test_cmp expect actual
f92f2038
DA
161'
162
163# Test the $GIT_*_TOOL variables and ensure
164# that $GIT_DIFF_TOOL always wins unless --tool is specified
2c4f3026 165test_expect_success PERL 'GIT_DIFF_TOOL overrides' '
e42360c4
DA
166 difftool_test_setup &&
167 test_config diff.tool bogus-tool &&
168 test_config merge.tool bogus-tool &&
f92f2038 169
e42360c4
DA
170 echo branch >expect &&
171 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
172 test_cmp expect actual &&
f92f2038 173
e42360c4
DA
174 test_config diff.tool bogus-tool &&
175 test_config merge.tool bogus-tool &&
176 GIT_DIFF_TOOL=bogus-tool \
177 git difftool --no-prompt --tool=test-tool branch >actual &&
178 test_cmp expect actual
f92f2038
DA
179'
180
181# Test that we don't have to pass --no-prompt to difftool
182# when $GIT_DIFFTOOL_NO_PROMPT is true
2c4f3026 183test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' '
e42360c4
DA
184 difftool_test_setup &&
185 echo branch >expect &&
186 GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
187 test_cmp expect actual
f92f2038
DA
188'
189
a904392e
DA
190# git-difftool supports the difftool.prompt variable.
191# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
2c4f3026 192test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' '
e42360c4
DA
193 difftool_test_setup &&
194 test_config difftool.prompt false &&
195 echo >input &&
196 GIT_DIFFTOOL_PROMPT=true git difftool branch <input >output &&
197 prompt=$(tail -1 <output) &&
198 prompt_given "$prompt"
a904392e
DA
199'
200
201# Test that we don't have to pass --no-prompt when difftool.prompt is false
2c4f3026 202test_expect_success PERL 'difftool.prompt config variable is false' '
e42360c4
DA
203 difftool_test_setup &&
204 test_config difftool.prompt false &&
205 echo branch >expect &&
206 git difftool branch >actual &&
207 test_cmp expect actual
a904392e
DA
208'
209
a88183f1 210# Test that we don't have to pass --no-prompt when mergetool.prompt is false
2c4f3026 211test_expect_success PERL 'difftool merge.prompt = false' '
e42360c4 212 difftool_test_setup &&
bc0f35ca 213 test_might_fail git config --unset difftool.prompt &&
e42360c4
DA
214 test_config mergetool.prompt false &&
215 echo branch >expect &&
216 git difftool branch >actual &&
217 test_cmp expect actual
a88183f1
DA
218'
219
a904392e 220# Test that the -y flag can override difftool.prompt = true
2c4f3026 221test_expect_success PERL 'difftool.prompt can overridden with -y' '
e42360c4
DA
222 difftool_test_setup &&
223 test_config difftool.prompt true &&
224 echo branch >expect &&
225 git difftool -y branch >actual &&
226 test_cmp expect actual
a904392e
DA
227'
228
229# Test that the --prompt flag can override difftool.prompt = false
2c4f3026 230test_expect_success PERL 'difftool.prompt can overridden with --prompt' '
e42360c4
DA
231 difftool_test_setup &&
232 test_config difftool.prompt false &&
233 echo >input &&
234 git difftool --prompt branch <input >output &&
235 prompt=$(tail -1 <output) &&
236 prompt_given "$prompt"
a904392e
DA
237'
238
239# Test that the last flag passed on the command-line wins
2c4f3026 240test_expect_success PERL 'difftool last flag wins' '
e42360c4
DA
241 difftool_test_setup &&
242 echo branch >expect &&
243 git difftool --prompt --no-prompt branch >actual &&
244 test_cmp expect actual &&
245 echo >input &&
246 git difftool --no-prompt --prompt branch <input >output &&
247 prompt=$(tail -1 <output) &&
248 prompt_given "$prompt"
a904392e
DA
249'
250
f92f2038
DA
251# git-difftool falls back to git-mergetool config variables
252# so test that behavior here
2c4f3026 253test_expect_success PERL 'difftool + mergetool config variables' '
e42360c4
DA
254 test_config merge.tool test-tool &&
255 test_config mergetool.test-tool.cmd "cat \$LOCAL" &&
256 echo branch >expect &&
257 git difftool --no-prompt branch >actual &&
258 test_cmp expect actual &&
f92f2038
DA
259
260 # set merge.tool to something bogus, diff.tool to test-tool
e42360c4
DA
261 test_config merge.tool bogus-tool &&
262 test_config diff.tool test-tool &&
263 git difftool --no-prompt branch >actual &&
264 test_cmp expect actual
f92f2038
DA
265'
266
2c4f3026 267test_expect_success PERL 'difftool.<tool>.path' '
e42360c4
DA
268 test_config difftool.tkdiff.path echo &&
269 git difftool --tool=tkdiff --no-prompt branch >output &&
270 lines=$(grep file output | wc -l) &&
271 test "$lines" -eq 1
1c6f5b52
DA
272'
273
2c4f3026 274test_expect_success PERL 'difftool --extcmd=cat' '
e42360c4
DA
275 echo branch >expect &&
276 echo master >>expect &&
277 git difftool --no-prompt --extcmd=cat branch >actual &&
278 test_cmp expect actual
f47f1e2c 279'
1c6f5b52 280
2c4f3026 281test_expect_success PERL 'difftool --extcmd cat' '
e42360c4
DA
282 echo branch >expect &&
283 echo master >>expect &&
284 git difftool --no-prompt --extcmd=cat branch >actual &&
285 test_cmp expect actual
f47f1e2c 286'
1c6f5b52 287
2c4f3026 288test_expect_success PERL 'difftool -x cat' '
e42360c4
DA
289 echo branch >expect &&
290 echo master >>expect &&
291 git difftool --no-prompt -x cat branch >actual &&
292 test_cmp expect actual
9f3d54d1
DA
293'
294
2c4f3026 295test_expect_success PERL 'difftool --extcmd echo arg1' '
e42360c4
DA
296 echo file >expect &&
297 git difftool --no-prompt \
298 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
299 test_cmp expect actual
9f3d54d1 300'
1c6f5b52 301
2c4f3026 302test_expect_success PERL 'difftool --extcmd cat arg1' '
e42360c4
DA
303 echo master >expect &&
304 git difftool --no-prompt \
305 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
306 test_cmp expect actual
9f3d54d1 307'
1c6f5b52 308
2c4f3026 309test_expect_success PERL 'difftool --extcmd cat arg2' '
e42360c4
DA
310 echo branch >expect &&
311 git difftool --no-prompt \
312 --extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
313 test_cmp expect actual
f92f2038
DA
314'
315
ba959de1
SC
316# Create a second file on master and a different version on branch
317test_expect_success PERL 'setup with 2 files different' '
318 echo m2 >file2 &&
319 git add file2 &&
320 git commit -m "added file2" &&
321
322 git checkout branch &&
323 echo br2 >file2 &&
324 git add file2 &&
325 git commit -a -m "branch changed file2" &&
326 git checkout master
327'
328
329test_expect_success PERL 'say no to the first file' '
e42360c4
DA
330 (echo n && echo) >input &&
331 git difftool -x cat branch <input >output &&
472353a5
JK
332 grep m2 output &&
333 grep br2 output &&
334 ! grep master output &&
335 ! grep branch output
ba959de1
SC
336'
337
338test_expect_success PERL 'say no to the second file' '
e42360c4
DA
339 (echo && echo n) >input &&
340 git difftool -x cat branch <input >output &&
472353a5
JK
341 grep master output &&
342 grep branch output &&
343 ! grep m2 output &&
344 ! grep br2 output
ba959de1
SC
345'
346
25098690
JS
347test_expect_success PERL 'ending prompt input with EOF' '
348 git difftool -x cat branch </dev/null >output &&
349 ! grep master output &&
350 ! grep branch output &&
351 ! grep m2 output &&
352 ! grep br2 output
353'
354
bf73fc21 355test_expect_success PERL 'difftool --tool-help' '
e42360c4 356 git difftool --tool-help >output &&
472353a5 357 grep tool output
bf73fc21
TH
358'
359
7e0abcec
TH
360test_expect_success PERL 'setup change in subdirectory' '
361 git checkout master &&
362 mkdir sub &&
363 echo master >sub/sub &&
364 git add sub/sub &&
365 git commit -m "added sub/sub" &&
366 echo test >>file &&
367 echo test >>sub/sub &&
3caf5a93 368 git add file sub/sub &&
7e0abcec
TH
369 git commit -m "modified both"
370'
371
e01afdb7
JK
372run_dir_diff_test () {
373 test_expect_success PERL "$1 --no-symlinks" "
374 symlinks=--no-symlinks &&
375 $2
376 "
377 test_expect_success PERL,SYMLINKS "$1 --symlinks" "
378 symlinks=--symlinks &&
379 $2
380 "
381}
382
383run_dir_diff_test 'difftool -d' '
384 git difftool -d $symlinks --extcmd ls branch >output &&
472353a5
JK
385 grep sub output &&
386 grep file output
7e0abcec
TH
387'
388
e01afdb7
JK
389run_dir_diff_test 'difftool --dir-diff' '
390 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
472353a5
JK
391 grep sub output &&
392 grep file output
7e0abcec
TH
393'
394
e01afdb7
JK
395run_dir_diff_test 'difftool --dir-diff ignores --prompt' '
396 git difftool --dir-diff $symlinks --prompt --extcmd ls branch >output &&
472353a5
JK
397 grep sub output &&
398 grep file output
bf341b90
JK
399'
400
e01afdb7 401run_dir_diff_test 'difftool --dir-diff from subdirectory' '
bf341b90
JK
402 (
403 cd sub &&
e01afdb7 404 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
472353a5
JK
405 grep sub output &&
406 grep file output
bf341b90
JK
407 )
408'
409
1f197a1d
JK
410run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
411 test_when_finished git reset --hard &&
412 rm file2 &&
413 git difftool --dir-diff $symlinks --extcmd ls branch master >output &&
414 grep file2 output
415'
416
02c56314
JK
417write_script .git/CHECK_SYMLINKS <<\EOF
418for f in file file2 sub/sub
419do
420 echo "$f"
421 readlink "$2/$f"
422done >actual
423EOF
424
425test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' '
426 cat >expect <<-EOF &&
427 file
428 $(pwd)/file
429 file2
430 $(pwd)/file2
431 sub/sub
432 $(pwd)/sub/sub
433 EOF
434 git difftool --dir-diff --symlink \
435 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
436 test_cmp actual expect
437'
438
32eaf1de
KS
439write_script modify-right-file <<\EOF
440echo "new content" >"$2/file"
441EOF
442
443run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
444 test_when_finished git reset --hard &&
445 echo "orig content" >file &&
446 git difftool -d $symlinks --extcmd "$(pwd)/modify-right-file" branch &&
447 echo "new content" >expect &&
448 test_cmp expect file
449'
450
451run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
452 test_when_finished git reset --hard &&
453 git difftool -d $symlinks --extcmd "$(pwd)/modify-right-file" branch &&
454 echo "new content" >expect &&
455 test_cmp expect file
456'
457
67aa147a
JK
458write_script modify-file <<\EOF
459echo "new content" >file
460EOF
461
462test_expect_success PERL 'difftool --no-symlinks does not overwrite working tree file ' '
463 echo "orig content" >file &&
464 git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-file" branch &&
465 echo "new content" >expect &&
466 test_cmp expect file
467'
468
469write_script modify-both-files <<\EOF
470echo "wt content" >file &&
471echo "tmp content" >"$2/file" &&
472echo "$2" >tmpdir
473EOF
474
475test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
476 (
477 TMPDIR=$TRASH_DIRECTORY &&
478 export TMPDIR &&
479 echo "orig content" >file &&
480 test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-both-files" branch &&
481 echo "wt content" >expect &&
482 test_cmp expect file &&
483 echo "tmp content" >expect &&
484 test_cmp expect "$(cat tmpdir)/file"
485 )
486'
487
fcfec8bd
JH
488test_expect_success PERL 'difftool properly honors gitlink and core.worktree' '
489 git submodule add ./. submod/ule &&
490 (
491 cd submod/ule &&
492 test_config diff.tool checktrees &&
493 test_config difftool.checktrees.cmd '\''
494 test -d "$LOCAL" && test -d "$REMOTE" && echo good
495 '\'' &&
496 echo good >expect &&
497 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
498 test_cmp expect actual
499 )
500'
501
f92f2038 502test_done