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