Merge branch 'po/bundle-doc-clonable'
[git] / t / t7800-difftool.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
4 #
5
6 test_description='git-difftool
7
8 Testing basic diff tool invocation
9 '
10
11 . ./test-lib.sh
12
13 difftool_test_setup ()
14 {
15         test_config diff.tool test-tool &&
16         test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
17         test_config difftool.bogus-tool.cmd false
18 }
19
20 prompt_given ()
21 {
22         prompt="$1"
23         test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
24 }
25
26 test_expect_success 'basic usage requires no repo' '
27         test_expect_code 129 git difftool -h >output &&
28         test_i18ngrep ^usage: output &&
29         # create a ceiling directory to prevent Git from finding a repo
30         mkdir -p not/repo &&
31         test_when_finished rm -r not &&
32         test_expect_code 129 \
33         env GIT_CEILING_DIRECTORIES="$(pwd)/not" \
34         git -C not/repo difftool -h >output &&
35         test_i18ngrep ^usage: output
36 '
37
38 # Create a file on master and change it on branch
39 test_expect_success 'setup' '
40         echo master >file &&
41         git add file &&
42         git commit -m "added file" &&
43
44         git checkout -b branch master &&
45         echo branch >file &&
46         git commit -a -m "branch changed file" &&
47         git checkout master
48 '
49
50 # Configure a custom difftool.<tool>.cmd and use it
51 test_expect_success 'custom commands' '
52         difftool_test_setup &&
53         test_config difftool.test-tool.cmd "cat \"\$REMOTE\"" &&
54         echo master >expect &&
55         git difftool --no-prompt branch >actual &&
56         test_cmp expect actual &&
57
58         test_config difftool.test-tool.cmd "cat \"\$LOCAL\"" &&
59         echo branch >expect &&
60         git difftool --no-prompt branch >actual &&
61         test_cmp expect actual
62 '
63
64 test_expect_success 'custom tool commands override built-ins' '
65         test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" &&
66         echo master >expect &&
67         git difftool --tool vimdiff --no-prompt branch >actual &&
68         test_cmp expect actual
69 '
70
71 test_expect_success 'difftool ignores bad --tool values' '
72         : >expect &&
73         test_must_fail \
74                 git difftool --no-prompt --tool=bad-tool branch >actual &&
75         test_cmp expect actual
76 '
77
78 test_expect_success 'difftool forwards arguments to diff' '
79         difftool_test_setup &&
80         >for-diff &&
81         git add for-diff &&
82         echo changes>for-diff &&
83         git add for-diff &&
84         : >expect &&
85         git difftool --cached --no-prompt -- for-diff >actual &&
86         test_cmp expect actual &&
87         git reset -- for-diff &&
88         rm for-diff
89 '
90
91 test_expect_success 'difftool ignores exit code' '
92         test_config difftool.error.cmd false &&
93         git difftool -y -t error branch
94 '
95
96 test_expect_success 'difftool forwards exit code with --trust-exit-code' '
97         test_config difftool.error.cmd false &&
98         test_must_fail git difftool -y --trust-exit-code -t error branch
99 '
100
101 test_expect_success 'difftool forwards exit code with --trust-exit-code for built-ins' '
102         test_config difftool.vimdiff.path false &&
103         test_must_fail git difftool -y --trust-exit-code -t vimdiff branch
104 '
105
106 test_expect_success 'difftool honors difftool.trustExitCode = true' '
107         test_config difftool.error.cmd false &&
108         test_config difftool.trustExitCode true &&
109         test_must_fail git difftool -y -t error branch
110 '
111
112 test_expect_success 'difftool honors difftool.trustExitCode = false' '
113         test_config difftool.error.cmd false &&
114         test_config difftool.trustExitCode false &&
115         git difftool -y -t error branch
116 '
117
118 test_expect_success 'difftool ignores exit code with --no-trust-exit-code' '
119         test_config difftool.error.cmd false &&
120         test_config difftool.trustExitCode true &&
121         git difftool -y --no-trust-exit-code -t error branch
122 '
123
124 test_expect_success 'difftool stops on error with --trust-exit-code' '
125         test_when_finished "rm -f for-diff .git/fail-right-file" &&
126         test_when_finished "git reset -- for-diff" &&
127         write_script .git/fail-right-file <<-\EOF &&
128         echo "$2"
129         exit 1
130         EOF
131         >for-diff &&
132         git add for-diff &&
133         echo file >expect &&
134         test_must_fail git difftool -y --trust-exit-code \
135                 --extcmd .git/fail-right-file branch >actual &&
136         test_cmp expect actual
137 '
138
139 test_expect_success 'difftool honors exit status if command not found' '
140         test_config difftool.nonexistent.cmd i-dont-exist &&
141         test_config difftool.trustExitCode false &&
142         test_must_fail git difftool -y -t nonexistent branch
143 '
144
145 test_expect_success 'difftool honors --gui' '
146         difftool_test_setup &&
147         test_config merge.tool bogus-tool &&
148         test_config diff.tool bogus-tool &&
149         test_config diff.guitool test-tool &&
150
151         echo branch >expect &&
152         git difftool --no-prompt --gui branch >actual &&
153         test_cmp expect actual
154 '
155
156 test_expect_success 'difftool --gui last setting wins' '
157         difftool_test_setup &&
158         : >expect &&
159         git difftool --no-prompt --gui --no-gui >actual &&
160         test_cmp expect actual &&
161
162         test_config merge.tool bogus-tool &&
163         test_config diff.tool bogus-tool &&
164         test_config diff.guitool test-tool &&
165         echo branch >expect &&
166         git difftool --no-prompt --no-gui --gui branch >actual &&
167         test_cmp expect actual
168 '
169
170 test_expect_success 'difftool --gui works without configured diff.guitool' '
171         difftool_test_setup &&
172         echo branch >expect &&
173         git difftool --no-prompt --gui branch >actual &&
174         test_cmp expect actual
175 '
176
177 # Specify the diff tool using $GIT_DIFF_TOOL
178 test_expect_success 'GIT_DIFF_TOOL variable' '
179         difftool_test_setup &&
180         git config --unset diff.tool &&
181         echo branch >expect &&
182         GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
183         test_cmp expect actual
184 '
185
186 # Test the $GIT_*_TOOL variables and ensure
187 # that $GIT_DIFF_TOOL always wins unless --tool is specified
188 test_expect_success 'GIT_DIFF_TOOL overrides' '
189         difftool_test_setup &&
190         test_config diff.tool bogus-tool &&
191         test_config merge.tool bogus-tool &&
192
193         echo branch >expect &&
194         GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
195         test_cmp expect actual &&
196
197         test_config diff.tool bogus-tool &&
198         test_config merge.tool bogus-tool &&
199         GIT_DIFF_TOOL=bogus-tool \
200                 git difftool --no-prompt --tool=test-tool branch >actual &&
201         test_cmp expect actual
202 '
203
204 # Test that we don't have to pass --no-prompt to difftool
205 # when $GIT_DIFFTOOL_NO_PROMPT is true
206 test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
207         difftool_test_setup &&
208         echo branch >expect &&
209         GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
210         test_cmp expect actual
211 '
212
213 # git-difftool supports the difftool.prompt variable.
214 # Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
215 test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '
216         difftool_test_setup &&
217         test_config difftool.prompt false &&
218         echo >input &&
219         GIT_DIFFTOOL_PROMPT=true git difftool branch <input >output &&
220         prompt=$(tail -1 <output) &&
221         prompt_given "$prompt"
222 '
223
224 # Test that we don't have to pass --no-prompt when difftool.prompt is false
225 test_expect_success 'difftool.prompt config variable is false' '
226         difftool_test_setup &&
227         test_config difftool.prompt false &&
228         echo branch >expect &&
229         git difftool branch >actual &&
230         test_cmp expect actual
231 '
232
233 # Test that we don't have to pass --no-prompt when mergetool.prompt is false
234 test_expect_success 'difftool merge.prompt = false' '
235         difftool_test_setup &&
236         test_might_fail git config --unset difftool.prompt &&
237         test_config mergetool.prompt false &&
238         echo branch >expect &&
239         git difftool branch >actual &&
240         test_cmp expect actual
241 '
242
243 # Test that the -y flag can override difftool.prompt = true
244 test_expect_success 'difftool.prompt can overridden with -y' '
245         difftool_test_setup &&
246         test_config difftool.prompt true &&
247         echo branch >expect &&
248         git difftool -y branch >actual &&
249         test_cmp expect actual
250 '
251
252 # Test that the --prompt flag can override difftool.prompt = false
253 test_expect_success 'difftool.prompt can overridden with --prompt' '
254         difftool_test_setup &&
255         test_config difftool.prompt false &&
256         echo >input &&
257         git difftool --prompt branch <input >output &&
258         prompt=$(tail -1 <output) &&
259         prompt_given "$prompt"
260 '
261
262 # Test that the last flag passed on the command-line wins
263 test_expect_success 'difftool last flag wins' '
264         difftool_test_setup &&
265         echo branch >expect &&
266         git difftool --prompt --no-prompt branch >actual &&
267         test_cmp expect actual &&
268         echo >input &&
269         git difftool --no-prompt --prompt branch <input >output &&
270         prompt=$(tail -1 <output) &&
271         prompt_given "$prompt"
272 '
273
274 # git-difftool falls back to git-mergetool config variables
275 # so test that behavior here
276 test_expect_success 'difftool + mergetool config variables' '
277         test_config merge.tool test-tool &&
278         test_config mergetool.test-tool.cmd "cat \$LOCAL" &&
279         echo branch >expect &&
280         git difftool --no-prompt branch >actual &&
281         test_cmp expect actual &&
282         git difftool --gui --no-prompt branch >actual &&
283         test_cmp expect actual &&
284
285         # set merge.tool to something bogus, diff.tool to test-tool
286         test_config merge.tool bogus-tool &&
287         test_config diff.tool test-tool &&
288         git difftool --no-prompt branch >actual &&
289         test_cmp expect actual &&
290         git difftool --gui --no-prompt branch >actual &&
291         test_cmp expect actual &&
292
293         # set merge.tool, diff.tool to something bogus, merge.guitool to test-tool
294         test_config diff.tool bogus-tool &&
295         test_config merge.guitool test-tool &&
296         git difftool --gui --no-prompt branch >actual &&
297         test_cmp expect actual &&
298
299         # set merge.tool, diff.tool, merge.guitool to something bogus, diff.guitool to test-tool
300         test_config merge.guitool bogus-tool &&
301         test_config diff.guitool test-tool &&
302         git difftool --gui --no-prompt branch >actual &&
303         test_cmp expect actual
304 '
305
306 test_expect_success 'difftool.<tool>.path' '
307         test_config difftool.tkdiff.path echo &&
308         git difftool --tool=tkdiff --no-prompt branch >output &&
309         grep file output >grep-output &&
310         test_line_count = 1 grep-output
311 '
312
313 test_expect_success 'difftool --extcmd=cat' '
314         echo branch >expect &&
315         echo master >>expect &&
316         git difftool --no-prompt --extcmd=cat branch >actual &&
317         test_cmp expect actual
318 '
319
320 test_expect_success 'difftool --extcmd cat' '
321         echo branch >expect &&
322         echo master >>expect &&
323         git difftool --no-prompt --extcmd=cat branch >actual &&
324         test_cmp expect actual
325 '
326
327 test_expect_success 'difftool -x cat' '
328         echo branch >expect &&
329         echo master >>expect &&
330         git difftool --no-prompt -x cat branch >actual &&
331         test_cmp expect actual
332 '
333
334 test_expect_success 'difftool --extcmd echo arg1' '
335         echo file >expect &&
336         git difftool --no-prompt \
337                 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
338         test_cmp expect actual
339 '
340
341 test_expect_success 'difftool --extcmd cat arg1' '
342         echo master >expect &&
343         git difftool --no-prompt \
344                 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
345         test_cmp expect actual
346 '
347
348 test_expect_success 'difftool --extcmd cat arg2' '
349         echo branch >expect &&
350         git difftool --no-prompt \
351                 --extcmd sh\ -c\ \"cat\ \\\"\$2\\\"\" branch >actual &&
352         test_cmp expect actual
353 '
354
355 # Create a second file on master and a different version on branch
356 test_expect_success 'setup with 2 files different' '
357         echo m2 >file2 &&
358         git add file2 &&
359         git commit -m "added file2" &&
360
361         git checkout branch &&
362         echo br2 >file2 &&
363         git add file2 &&
364         git commit -a -m "branch changed file2" &&
365         git checkout master
366 '
367
368 test_expect_success 'say no to the first file' '
369         (echo n && echo) >input &&
370         git difftool -x cat branch <input >output &&
371         grep m2 output &&
372         grep br2 output &&
373         ! grep master output &&
374         ! grep branch output
375 '
376
377 test_expect_success 'say no to the second file' '
378         (echo && echo n) >input &&
379         git difftool -x cat branch <input >output &&
380         grep master output &&
381         grep branch output &&
382         ! grep m2 output &&
383         ! grep br2 output
384 '
385
386 test_expect_success 'ending prompt input with EOF' '
387         git difftool -x cat branch </dev/null >output &&
388         ! grep master output &&
389         ! grep branch output &&
390         ! grep m2 output &&
391         ! grep br2 output
392 '
393
394 test_expect_success 'difftool --tool-help' '
395         git difftool --tool-help >output &&
396         grep tool output
397 '
398
399 test_expect_success 'setup change in subdirectory' '
400         git checkout master &&
401         mkdir sub &&
402         echo master >sub/sub &&
403         git add sub/sub &&
404         git commit -m "added sub/sub" &&
405         git tag v1 &&
406         echo test >>file &&
407         echo test >>sub/sub &&
408         git add file sub/sub &&
409         git commit -m "modified both"
410 '
411
412 test_expect_success 'difftool -d with growing paths' '
413         a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
414         git init growing &&
415         (
416                 cd growing &&
417                 echo "test -f \"\$2/b\"" | write_script .git/test-for-b.sh &&
418                 one=$(printf 1 | git hash-object -w --stdin) &&
419                 two=$(printf 2 | git hash-object -w --stdin) &&
420                 git update-index --add \
421                         --cacheinfo 100644,$one,$a --cacheinfo 100644,$two,b &&
422                 tree1=$(git write-tree) &&
423                 git update-index --add \
424                         --cacheinfo 100644,$two,$a --cacheinfo 100644,$one,b &&
425                 tree2=$(git write-tree) &&
426                 git checkout -- $a &&
427                 git difftool -d --extcmd .git/test-for-b.sh $tree1 $tree2
428         )
429 '
430
431 run_dir_diff_test () {
432         test_expect_success "$1 --no-symlinks" "
433                 symlinks=--no-symlinks &&
434                 $2
435         "
436         test_expect_success SYMLINKS "$1 --symlinks" "
437                 symlinks=--symlinks &&
438                 $2
439         "
440 }
441
442 run_dir_diff_test 'difftool -d' '
443         git difftool -d $symlinks --extcmd ls branch >output &&
444         grep sub output &&
445         grep file output
446 '
447
448 run_dir_diff_test 'difftool --dir-diff' '
449         git difftool --dir-diff $symlinks --extcmd ls branch >output &&
450         grep sub output &&
451         grep file output
452 '
453
454 run_dir_diff_test 'difftool --dir-diff ignores --prompt' '
455         git difftool --dir-diff $symlinks --prompt --extcmd ls branch >output &&
456         grep sub output &&
457         grep file output
458 '
459
460 run_dir_diff_test 'difftool --dir-diff branch from subdirectory' '
461         (
462                 cd sub &&
463                 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
464                 # "sub" must only exist in "right"
465                 # "file" and "file2" must be listed in both "left" and "right"
466                 grep sub output >sub-output &&
467                 test_line_count = 1 sub-output &&
468                 grep file"$" output >file-output &&
469                 test_line_count = 2 file-output &&
470                 grep file2 output >file2-output &&
471                 test_line_count = 2 file2-output
472         )
473 '
474
475 run_dir_diff_test 'difftool --dir-diff v1 from subdirectory' '
476         (
477                 cd sub &&
478                 git difftool --dir-diff $symlinks --extcmd ls v1 >output &&
479                 # "sub" and "file" exist in both v1 and HEAD.
480                 # "file2" is unchanged.
481                 grep sub output >sub-output &&
482                 test_line_count = 2 sub-output &&
483                 grep file output >file-output &&
484                 test_line_count = 2 file-output &&
485                 ! grep file2 output
486         )
487 '
488
489 run_dir_diff_test 'difftool --dir-diff branch from subdirectory w/ pathspec' '
490         (
491                 cd sub &&
492                 git difftool --dir-diff $symlinks --extcmd ls branch -- .>output &&
493                 # "sub" only exists in "right"
494                 # "file" and "file2" must not be listed
495                 grep sub output >sub-output &&
496                 test_line_count = 1 sub-output &&
497                 ! grep file output
498         )
499 '
500
501 run_dir_diff_test 'difftool --dir-diff v1 from subdirectory w/ pathspec' '
502         (
503                 cd sub &&
504                 git difftool --dir-diff $symlinks --extcmd ls v1 -- .>output &&
505                 # "sub" exists in v1 and HEAD
506                 # "file" is filtered out by the pathspec
507                 grep sub output >sub-output &&
508                 test_line_count = 2 sub-output &&
509                 ! grep file output
510         )
511 '
512
513 run_dir_diff_test 'difftool --dir-diff from subdirectory with GIT_DIR set' '
514         (
515                 GIT_DIR=$(pwd)/.git &&
516                 export GIT_DIR &&
517                 GIT_WORK_TREE=$(pwd) &&
518                 export GIT_WORK_TREE &&
519                 cd sub &&
520                 git difftool --dir-diff $symlinks --extcmd ls \
521                         branch -- sub >output &&
522                 grep sub output &&
523                 ! grep file output
524         )
525 '
526
527 run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
528         test_when_finished git reset --hard &&
529         rm file2 &&
530         git difftool --dir-diff $symlinks --extcmd ls branch master >output &&
531         grep file2 output
532 '
533
534 run_dir_diff_test 'difftool --dir-diff with unmerged files' '
535         test_when_finished git reset --hard &&
536         test_config difftool.echo.cmd "echo ok" &&
537         git checkout -B conflict-a &&
538         git checkout -B conflict-b &&
539         git checkout conflict-a &&
540         echo a >>file &&
541         git add file &&
542         git commit -m conflict-a &&
543         git checkout conflict-b &&
544         echo b >>file &&
545         git add file &&
546         git commit -m conflict-b &&
547         git checkout master &&
548         git merge conflict-a &&
549         test_must_fail git merge conflict-b &&
550         cat >expect <<-EOF &&
551                 ok
552         EOF
553         git difftool --dir-diff $symlinks -t echo >actual &&
554         test_cmp expect actual
555 '
556
557 write_script .git/CHECK_SYMLINKS <<\EOF
558 for f in file file2 sub/sub
559 do
560         echo "$f"
561         ls -ld "$2/$f" | sed -e 's/.* -> //'
562 done >actual
563 EOF
564
565 test_expect_success SYMLINKS 'difftool --dir-diff --symlinks without unstaged changes' '
566         cat >expect <<-EOF &&
567         file
568         $PWD/file
569         file2
570         $PWD/file2
571         sub/sub
572         $PWD/sub/sub
573         EOF
574         git difftool --dir-diff --symlinks \
575                 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
576         test_cmp expect actual
577 '
578
579 write_script modify-right-file <<\EOF
580 echo "new content" >"$2/file"
581 EOF
582
583 run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
584         test_when_finished git reset --hard &&
585         echo "orig content" >file &&
586         git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
587         echo "new content" >expect &&
588         test_cmp expect file
589 '
590
591 run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
592         test_when_finished git reset --hard &&
593         git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
594         echo "new content" >expect &&
595         test_cmp expect file
596 '
597
598 write_script modify-file <<\EOF
599 echo "new content" >file
600 EOF
601
602 test_expect_success 'difftool --no-symlinks does not overwrite working tree file ' '
603         echo "orig content" >file &&
604         git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-file" branch &&
605         echo "new content" >expect &&
606         test_cmp expect file
607 '
608
609 write_script modify-both-files <<\EOF
610 echo "wt content" >file &&
611 echo "tmp content" >"$2/file" &&
612 echo "$2" >tmpdir
613 EOF
614
615 test_expect_success 'difftool --no-symlinks detects conflict ' '
616         (
617                 TMPDIR=$TRASH_DIRECTORY &&
618                 export TMPDIR &&
619                 echo "orig content" >file &&
620                 test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-both-files" branch &&
621                 echo "wt content" >expect &&
622                 test_cmp expect file &&
623                 echo "tmp content" >expect &&
624                 test_cmp expect "$(cat tmpdir)/file"
625         )
626 '
627
628 test_expect_success 'difftool properly honors gitlink and core.worktree' '
629         test_when_finished rm -rf submod/ule &&
630         git submodule add ./. submod/ule &&
631         test_config -C submod/ule diff.tool checktrees &&
632         test_config -C submod/ule difftool.checktrees.cmd '\''
633                 test -d "$LOCAL" && test -d "$REMOTE" && echo good
634                 '\'' &&
635         (
636                 cd submod/ule &&
637                 echo good >expect &&
638                 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
639                 test_cmp expect actual &&
640                 rm -f expect actual
641         )
642 '
643
644 test_expect_success SYMLINKS 'difftool --dir-diff symlinked directories' '
645         test_when_finished git reset --hard &&
646         git init dirlinks &&
647         (
648                 cd dirlinks &&
649                 git config diff.tool checktrees &&
650                 git config difftool.checktrees.cmd "echo good" &&
651                 mkdir foo &&
652                 : >foo/bar &&
653                 git add foo/bar &&
654                 test_commit symlink-one &&
655                 ln -s foo link &&
656                 git add link &&
657                 test_commit symlink-two &&
658                 echo good >expect &&
659                 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
660                 test_cmp expect actual
661         )
662 '
663
664 test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
665         test_when_finished git reset --hard &&
666         touch b &&
667         ln -s b c &&
668         git add b c &&
669         test_tick &&
670         git commit -m initial &&
671         touch d &&
672         rm c &&
673         ln -s d c &&
674         cat >expect <<-EOF &&
675                 b
676                 c
677
678                 c
679         EOF
680         git difftool --symlinks --dir-diff --extcmd ls >output &&
681         grep -v ^/ output >actual &&
682         test_cmp expect actual &&
683
684         git difftool --no-symlinks --dir-diff --extcmd ls >output &&
685         grep -v ^/ output >actual &&
686         test_cmp expect actual &&
687
688         # The left side contains symlink "c" that points to "b"
689         test_config difftool.cat.cmd "cat \$LOCAL/c" &&
690         printf "%s\n" b >expect &&
691
692         git difftool --symlinks --dir-diff --tool cat >actual &&
693         test_cmp expect actual &&
694
695         git difftool --symlinks --no-symlinks --dir-diff --tool cat >actual &&
696         test_cmp expect actual &&
697
698         # The right side contains symlink "c" that points to "d"
699         test_config difftool.cat.cmd "cat \$REMOTE/c" &&
700         printf "%s\n" d >expect &&
701
702         git difftool --symlinks --dir-diff --tool cat >actual &&
703         test_cmp expect actual &&
704
705         git difftool --no-symlinks --dir-diff --tool cat >actual &&
706         test_cmp expect actual &&
707
708         # Deleted symlinks
709         rm -f c &&
710         cat >expect <<-EOF &&
711                 b
712                 c
713
714         EOF
715         git difftool --symlinks --dir-diff --extcmd ls >output &&
716         grep -v ^/ output >actual &&
717         test_cmp expect actual &&
718
719         git difftool --no-symlinks --dir-diff --extcmd ls >output &&
720         grep -v ^/ output >actual &&
721         test_cmp expect actual
722 '
723
724 test_expect_success 'outside worktree' '
725         echo 1 >1 &&
726         echo 2 >2 &&
727         test_expect_code 1 nongit git \
728                 -c diff.tool=echo -c difftool.echo.cmd="echo \$LOCAL \$REMOTE" \
729                 difftool --no-prompt --no-index ../1 ../2 >actual &&
730         echo "../1 ../2" >expect &&
731         test_cmp expect actual
732 '
733
734 test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive' '
735         difftool_test_setup &&
736         test_must_fail git difftool --gui --tool=test-tool &&
737         test_must_fail git difftool --gui --extcmd=cat &&
738         test_must_fail git difftool --tool=test-tool --extcmd=cat &&
739         test_must_fail git difftool --gui --tool=test-tool --extcmd=cat
740 '
741
742 test_done