Merge branch 'da/difftool-dir-diff-symlink-fix' into maint
[git/debian.git] / t / t7800-difftool.sh
blob528e0dabf08653b73f2bc9ced333d4c79fa70daf
1 #!/bin/sh
3 # Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
6 test_description='git-difftool
8 Testing basic diff tool invocation
11 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
12 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14 . ./test-lib.sh
16 difftool_test_setup ()
18 test_config diff.tool test-tool &&
19 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
20 test_config difftool.bogus-tool.cmd false
23 prompt_given ()
25 prompt="$1"
26 test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
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
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" &&
47 git checkout -b branch main &&
48 echo branch >file &&
49 git commit -a -m "branch changed file" &&
50 git checkout main
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 &&
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
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
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
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
94 test_expect_success 'difftool ignores exit code' '
95 test_config difftool.error.cmd false &&
96 git difftool -y -t error branch
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
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
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
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
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
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
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
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
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 &&
153 echo branch >expect &&
154 git difftool --no-prompt --gui branch >actual &&
155 test_cmp expect actual
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 &&
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
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
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
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 &&
195 echo branch >expect &&
196 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
197 test_cmp expect actual &&
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
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
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"
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
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
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
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"
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"
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 &&
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 &&
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 &&
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
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
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
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
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
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
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
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
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" &&
363 git checkout branch &&
364 echo br2 >file2 &&
365 git add file2 &&
366 git commit -a -m "branch changed file2" &&
367 git checkout main
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
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
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
396 test_expect_success 'difftool --tool-help' '
397 git difftool --tool-help >output &&
398 grep tool output
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"
414 test_expect_success 'difftool -d with growing paths' '
415 a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
416 git init growing &&
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
433 run_dir_diff_test () {
434 test_expect_success "$1 --no-symlinks" "
435 symlinks=--no-symlinks &&
438 test_expect_success SYMLINKS "$1 --symlinks" "
439 symlinks=--symlinks &&
444 run_dir_diff_test 'difftool -d' '
445 git difftool -d $symlinks --extcmd ls branch >output &&
446 grep "^sub$" output &&
447 grep "^file$" output
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
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
462 run_dir_diff_test 'difftool --dir-diff branch from subdirectory' '
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
477 run_dir_diff_test 'difftool --dir-diff v1 from subdirectory' '
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
491 run_dir_diff_test 'difftool --dir-diff branch from subdirectory w/ pathspec' '
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
503 run_dir_diff_test 'difftool --dir-diff v1 from subdirectory w/ pathspec' '
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
515 run_dir_diff_test 'difftool --dir-diff from subdirectory with GIT_DIR set' '
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
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
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 &&
555 git difftool --dir-diff $symlinks -t echo >actual &&
556 test_cmp expect actual
559 write_script .git/CHECK_SYMLINKS <<\EOF
560 for f in file file2 sub/sub
562 echo "$f"
563 ls -ld "$2/$f" | sed -e 's/.* -> //'
564 done >actual
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
576 git difftool --dir-diff --symlinks \
577 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
578 test_cmp expect actual
581 write_script modify-right-file <<\EOF
582 echo "new content" >"$2/file"
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
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
600 write_script modify-file <<\EOF
601 echo "new content" >file
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
611 write_script modify-both-files <<\EOF
612 echo "wt content" >file &&
613 echo "tmp content" >"$2/file" &&
614 echo "$2" >tmpdir
617 test_expect_success 'difftool --no-symlinks detects conflict ' '
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"
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 '\'' &&
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
646 test_expect_success SYMLINKS 'difftool --dir-diff symlinked directories' '
647 test_when_finished git reset --hard &&
648 git init dirlinks &&
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
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 &&
681 git difftool --symlinks --dir-diff --extcmd ls >output &&
682 grep -v ^/ output >actual &&
683 test_cmp expect actual &&
685 git difftool --no-symlinks --dir-diff --extcmd ls >output &&
686 grep -v ^/ output >actual &&
687 test_cmp expect actual &&
689 # The left side contains symlink "c" that points to "b"
690 test_config difftool.cat.cmd "cat \$LOCAL/c" &&
691 printf "%s\n" b >expect &&
693 git difftool --symlinks --dir-diff --tool cat >actual &&
694 test_cmp expect actual &&
696 git difftool --symlinks --no-symlinks --dir-diff --tool cat >actual &&
697 test_cmp expect actual &&
699 # The right side contains symlink "c" that points to "d"
700 test_config difftool.cat.cmd "cat \$REMOTE/c" &&
701 printf "%s\n" d >expect &&
703 git difftool --symlinks --dir-diff --tool cat >actual &&
704 test_cmp expect actual &&
706 git difftool --no-symlinks --dir-diff --tool cat >actual &&
707 test_cmp expect actual &&
709 # Deleted symlinks
710 rm -f c &&
711 cat >expect <<-EOF &&
715 git difftool --symlinks --dir-diff --extcmd ls >output &&
716 grep -v ^/ output >actual &&
717 test_cmp expect actual &&
719 git difftool --no-symlinks --dir-diff --extcmd ls >output &&
720 grep -v ^/ output >actual &&
721 test_cmp expect actual
724 test_expect_success SYMLINKS 'difftool --dir-diff writes symlinks as raw text' '
725 # Start out on a branch called "branch-init".
726 git init -b branch-init symlink-files &&
728 cd symlink-files &&
729 # This test ensures that symlinks are written as raw text.
730 # The "cat" tools output link and file contents.
731 git config difftool.cat-left-link.cmd "cat \"\$LOCAL/link\"" &&
732 git config difftool.cat-left-a.cmd "cat \"\$LOCAL/file-a\"" &&
733 git config difftool.cat-right-link.cmd "cat \"\$REMOTE/link\"" &&
734 git config difftool.cat-right-b.cmd "cat \"\$REMOTE/file-b\"" &&
736 # Record the empty initial state so that we can come back here
737 # later and not have to consider the any cases where difftool
738 # will create symlinks back into the worktree.
739 test_tick &&
740 git commit --allow-empty -m init &&
742 # Create a file called "file-a" with a symlink pointing to it.
743 git switch -c branch-a &&
744 echo a >file-a &&
745 ln -s file-a link &&
746 git add file-a link &&
747 test_tick &&
748 git commit -m link-to-file-a &&
750 # Create a file called "file-b" and point the symlink to it.
751 git switch -c branch-b &&
752 echo b >file-b &&
753 rm link &&
754 ln -s file-b link &&
755 git add file-b link &&
756 git rm file-a &&
757 test_tick &&
758 git commit -m link-to-file-b &&
760 # Checkout the initial branch so that the --symlinks behavior is
761 # not activated. The two directories should be completely
762 # independent with no symlinks pointing back here.
763 git switch branch-init &&
765 # The left link must be "file-a" and "file-a" must contain "a".
766 echo file-a >expect &&
767 git difftool --symlinks --dir-diff --tool cat-left-link \
768 branch-a branch-b >actual &&
769 test_cmp expect actual &&
771 echo a >expect &&
772 git difftool --symlinks --dir-diff --tool cat-left-a \
773 branch-a branch-b >actual &&
774 test_cmp expect actual &&
776 # The right link must be "file-b" and "file-b" must contain "b".
777 echo file-b >expect &&
778 git difftool --symlinks --dir-diff --tool cat-right-link \
779 branch-a branch-b >actual &&
780 test_cmp expect actual &&
782 echo b >expect &&
783 git difftool --symlinks --dir-diff --tool cat-right-b \
784 branch-a branch-b >actual &&
785 test_cmp expect actual
789 test_expect_success 'add -N and difftool -d' '
790 test_when_finished git reset --hard &&
792 test_write_lines A B C >intent-to-add &&
793 git add -N intent-to-add &&
794 git difftool --dir-diff --extcmd ls
797 test_expect_success 'difftool --cached with unmerged files' '
798 test_when_finished git reset --hard &&
800 test_commit conflicting &&
801 test_commit conflict-a conflict.t a &&
802 git reset --hard conflicting &&
803 test_commit conflict-b conflict.t b &&
804 test_must_fail git merge conflict-a &&
806 git difftool --cached --no-prompt >output &&
807 test_must_be_empty output
810 test_expect_success 'outside worktree' '
811 echo 1 >1 &&
812 echo 2 >2 &&
813 test_expect_code 1 nongit git \
814 -c diff.tool=echo -c difftool.echo.cmd="echo \$LOCAL \$REMOTE" \
815 difftool --no-prompt --no-index ../1 ../2 >actual &&
816 echo "../1 ../2" >expect &&
817 test_cmp expect actual
820 test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive' '
821 difftool_test_setup &&
822 test_must_fail git difftool --gui --tool=test-tool &&
823 test_must_fail git difftool --gui --extcmd=cat &&
824 test_must_fail git difftool --tool=test-tool --extcmd=cat &&
825 test_must_fail git difftool --gui --tool=test-tool --extcmd=cat
828 test_expect_success 'difftool --rotate-to' '
829 difftool_test_setup &&
830 test_when_finished git reset --hard &&
831 echo 1 >1 &&
832 echo 2 >2 &&
833 echo 4 >4 &&
834 git add 1 2 4 &&
835 git commit -a -m "124" &&
836 git difftool --no-prompt --extcmd=cat --rotate-to="2" HEAD^ >output &&
837 cat >expect <<-\EOF &&
842 test_cmp output expect
845 test_expect_success 'difftool --skip-to' '
846 difftool_test_setup &&
847 test_when_finished git reset --hard &&
848 git difftool --no-prompt --extcmd=cat --skip-to="2" HEAD^ >output &&
849 cat >expect <<-\EOF &&
853 test_cmp output expect
856 test_expect_success 'difftool --rotate/skip-to error condition' '
857 test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^ &&
858 test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
860 test_done