]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7800-difftool.sh
difftool: create a tmpdir path without repeated slashes
[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
1e2ae142 11GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
12export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
13
f92f2038
DA
14. ./test-lib.sh
15
e42360c4 16difftool_test_setup ()
f92f2038 17{
e42360c4
DA
18 test_config diff.tool test-tool &&
19 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
20 test_config difftool.bogus-tool.cmd false
f92f2038
DA
21}
22
e42360c4 23prompt_given ()
a904392e
DA
24{
25 prompt="$1"
cce076e3 26 test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
ba959de1
SC
27}
28
d81345ce 29test_expect_success 'basic usage requires no repo' '
e66adcad 30 test_expect_code 129 git difftool -h >output &&
0d75bfe6 31 test_i18ngrep ^usage: output &&
d81345ce
DA
32 # create a ceiling directory to prevent Git from finding a repo
33 mkdir -p not/repo &&
e66adcad
DA
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 &&
0d75bfe6 38 test_i18ngrep ^usage: output
d81345ce
DA
39'
40
1e2ae142 41# Create a file on main and change it on branch
019678d6 42test_expect_success 'setup' '
1e2ae142 43 echo main >file &&
f92f2038
DA
44 git add file &&
45 git commit -m "added file" &&
46
1e2ae142 47 git checkout -b branch main &&
f92f2038
DA
48 echo branch >file &&
49 git commit -a -m "branch changed file" &&
1e2ae142 50 git checkout main
f92f2038
DA
51'
52
53# Configure a custom difftool.<tool>.cmd and use it
019678d6 54test_expect_success 'custom commands' '
e42360c4
DA
55 difftool_test_setup &&
56 test_config difftool.test-tool.cmd "cat \"\$REMOTE\"" &&
1e2ae142 57 echo main >expect &&
e42360c4
DA
58 git difftool --no-prompt branch >actual &&
59 test_cmp expect actual &&
f92f2038 60
e42360c4
DA
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
f92f2038
DA
65'
66
019678d6 67test_expect_success 'custom tool commands override built-ins' '
f469e840 68 test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" &&
1e2ae142 69 echo main >expect &&
f469e840 70 git difftool --tool vimdiff --no-prompt branch >actual &&
e42360c4 71 test_cmp expect actual
a427ef7a
DA
72'
73
019678d6 74test_expect_success 'difftool ignores bad --tool values' '
e42360c4 75 : >expect &&
89294d14 76 test_must_fail \
e42360c4
DA
77 git difftool --no-prompt --tool=bad-tool branch >actual &&
78 test_cmp expect actual
f92f2038
DA
79'
80
019678d6 81test_expect_success 'difftool forwards arguments to diff' '
e42360c4 82 difftool_test_setup &&
d50b2c73
DA
83 >for-diff &&
84 git add for-diff &&
85 echo changes>for-diff &&
86 git add for-diff &&
e42360c4
DA
87 : >expect &&
88 git difftool --cached --no-prompt -- for-diff >actual &&
89 test_cmp expect actual &&
d50b2c73
DA
90 git reset -- for-diff &&
91 rm for-diff
92'
93
019678d6 94test_expect_success 'difftool ignores exit code' '
2b52123f
DA
95 test_config difftool.error.cmd false &&
96 git difftool -y -t error branch
97'
98
019678d6 99test_expect_success 'difftool forwards exit code with --trust-exit-code' '
2b52123f
DA
100 test_config difftool.error.cmd false &&
101 test_must_fail git difftool -y --trust-exit-code -t error branch
102'
103
019678d6 104test_expect_success 'difftool forwards exit code with --trust-exit-code for built-ins' '
99474b63
DA
105 test_config difftool.vimdiff.path false &&
106 test_must_fail git difftool -y --trust-exit-code -t vimdiff branch
107'
108
019678d6 109test_expect_success 'difftool honors difftool.trustExitCode = true' '
2b52123f
DA
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
019678d6 115test_expect_success 'difftool honors difftool.trustExitCode = false' '
2b52123f
DA
116 test_config difftool.error.cmd false &&
117 test_config difftool.trustExitCode false &&
118 git difftool -y -t error branch
119'
120
019678d6 121test_expect_success 'difftool ignores exit code with --no-trust-exit-code' '
2b52123f
DA
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
019678d6 127test_expect_success 'difftool stops on error with --trust-exit-code' '
2b52123f
DA
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 &&
e4837b44 131 echo failed
2b52123f
DA
132 exit 1
133 EOF
134 >for-diff &&
135 git add for-diff &&
2b52123f
DA
136 test_must_fail git difftool -y --trust-exit-code \
137 --extcmd .git/fail-right-file branch >actual &&
e4837b44 138 test_line_count = 1 actual
2b52123f
DA
139'
140
019678d6 141test_expect_success 'difftool honors exit status if command not found' '
45a4f5d9
JK
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
019678d6 147test_expect_success 'difftool honors --gui' '
e42360c4
DA
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 &&
4cefa495 152
e42360c4
DA
153 echo branch >expect &&
154 git difftool --no-prompt --gui branch >actual &&
155 test_cmp expect actual
4cefa495
DA
156'
157
019678d6 158test_expect_success 'difftool --gui last setting wins' '
e42360c4
DA
159 difftool_test_setup &&
160 : >expect &&
161 git difftool --no-prompt --gui --no-gui >actual &&
162 test_cmp expect actual &&
85089604 163
e42360c4
DA
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
85089604
TH
170'
171
019678d6 172test_expect_success 'difftool --gui works without configured diff.guitool' '
e42360c4
DA
173 difftool_test_setup &&
174 echo branch >expect &&
175 git difftool --no-prompt --gui branch >actual &&
176 test_cmp expect actual
42accaec
DA
177'
178
f92f2038 179# Specify the diff tool using $GIT_DIFF_TOOL
019678d6 180test_expect_success 'GIT_DIFF_TOOL variable' '
e42360c4
DA
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
f92f2038
DA
186'
187
188# Test the $GIT_*_TOOL variables and ensure
189# that $GIT_DIFF_TOOL always wins unless --tool is specified
019678d6 190test_expect_success 'GIT_DIFF_TOOL overrides' '
e42360c4
DA
191 difftool_test_setup &&
192 test_config diff.tool bogus-tool &&
193 test_config merge.tool bogus-tool &&
f92f2038 194
e42360c4
DA
195 echo branch >expect &&
196 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
197 test_cmp expect actual &&
f92f2038 198
e42360c4
DA
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
f92f2038
DA
204'
205
206# Test that we don't have to pass --no-prompt to difftool
207# when $GIT_DIFFTOOL_NO_PROMPT is true
019678d6 208test_expect_success 'GIT_DIFFTOOL_NO_PROMPT variable' '
e42360c4
DA
209 difftool_test_setup &&
210 echo branch >expect &&
211 GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
212 test_cmp expect actual
f92f2038
DA
213'
214
a904392e
DA
215# git-difftool supports the difftool.prompt variable.
216# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
019678d6 217test_expect_success 'GIT_DIFFTOOL_PROMPT variable' '
e42360c4
DA
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"
a904392e
DA
224'
225
226# Test that we don't have to pass --no-prompt when difftool.prompt is false
019678d6 227test_expect_success 'difftool.prompt config variable is false' '
e42360c4
DA
228 difftool_test_setup &&
229 test_config difftool.prompt false &&
230 echo branch >expect &&
231 git difftool branch >actual &&
232 test_cmp expect actual
a904392e
DA
233'
234
a88183f1 235# Test that we don't have to pass --no-prompt when mergetool.prompt is false
019678d6 236test_expect_success 'difftool merge.prompt = false' '
e42360c4 237 difftool_test_setup &&
bc0f35ca 238 test_might_fail git config --unset difftool.prompt &&
e42360c4
DA
239 test_config mergetool.prompt false &&
240 echo branch >expect &&
241 git difftool branch >actual &&
242 test_cmp expect actual
a88183f1
DA
243'
244
a904392e 245# Test that the -y flag can override difftool.prompt = true
019678d6 246test_expect_success 'difftool.prompt can overridden with -y' '
e42360c4
DA
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
a904392e
DA
252'
253
254# Test that the --prompt flag can override difftool.prompt = false
019678d6 255test_expect_success 'difftool.prompt can overridden with --prompt' '
e42360c4
DA
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"
a904392e
DA
262'
263
264# Test that the last flag passed on the command-line wins
019678d6 265test_expect_success 'difftool last flag wins' '
e42360c4
DA
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"
a904392e
DA
274'
275
f92f2038
DA
276# git-difftool falls back to git-mergetool config variables
277# so test that behavior here
019678d6 278test_expect_success 'difftool + mergetool config variables' '
e42360c4
DA
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 &&
6c22d715
DL
284 git difftool --gui --no-prompt branch >actual &&
285 test_cmp expect actual &&
f92f2038
DA
286
287 # set merge.tool to something bogus, diff.tool to test-tool
e42360c4
DA
288 test_config merge.tool bogus-tool &&
289 test_config diff.tool test-tool &&
290 git difftool --no-prompt branch >actual &&
6c22d715
DL
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 &&
e42360c4 305 test_cmp expect actual
f92f2038
DA
306'
307
019678d6 308test_expect_success 'difftool.<tool>.path' '
e42360c4
DA
309 test_config difftool.tkdiff.path echo &&
310 git difftool --tool=tkdiff --no-prompt branch >output &&
1ce515f0
DA
311 grep file output >grep-output &&
312 test_line_count = 1 grep-output
1c6f5b52
DA
313'
314
019678d6 315test_expect_success 'difftool --extcmd=cat' '
e42360c4 316 echo branch >expect &&
1e2ae142 317 echo main >>expect &&
e42360c4
DA
318 git difftool --no-prompt --extcmd=cat branch >actual &&
319 test_cmp expect actual
f47f1e2c 320'
1c6f5b52 321
019678d6 322test_expect_success 'difftool --extcmd cat' '
e42360c4 323 echo branch >expect &&
1e2ae142 324 echo main >>expect &&
e42360c4
DA
325 git difftool --no-prompt --extcmd=cat branch >actual &&
326 test_cmp expect actual
f47f1e2c 327'
1c6f5b52 328
019678d6 329test_expect_success 'difftool -x cat' '
e42360c4 330 echo branch >expect &&
1e2ae142 331 echo main >>expect &&
e42360c4
DA
332 git difftool --no-prompt -x cat branch >actual &&
333 test_cmp expect actual
9f3d54d1
DA
334'
335
019678d6 336test_expect_success 'difftool --extcmd echo arg1' '
e42360c4
DA
337 echo file >expect &&
338 git difftool --no-prompt \
339 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
340 test_cmp expect actual
9f3d54d1 341'
1c6f5b52 342
019678d6 343test_expect_success 'difftool --extcmd cat arg1' '
1e2ae142 344 echo main >expect &&
e42360c4
DA
345 git difftool --no-prompt \
346 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
347 test_cmp expect actual
9f3d54d1 348'
1c6f5b52 349
019678d6 350test_expect_success 'difftool --extcmd cat arg2' '
e42360c4
DA
351 echo branch >expect &&
352 git difftool --no-prompt \
665177eb 353 --extcmd sh\ -c\ \"cat\ \\\"\$2\\\"\" branch >actual &&
e42360c4 354 test_cmp expect actual
f92f2038
DA
355'
356
1e2ae142 357# Create a second file on main and a different version on branch
019678d6 358test_expect_success 'setup with 2 files different' '
ba959de1
SC
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" &&
1e2ae142 367 git checkout main
ba959de1
SC
368'
369
019678d6 370test_expect_success 'say no to the first file' '
e42360c4
DA
371 (echo n && echo) >input &&
372 git difftool -x cat branch <input >output &&
472353a5
JK
373 grep m2 output &&
374 grep br2 output &&
1e2ae142 375 ! grep main output &&
472353a5 376 ! grep branch output
ba959de1
SC
377'
378
019678d6 379test_expect_success 'say no to the second file' '
e42360c4
DA
380 (echo && echo n) >input &&
381 git difftool -x cat branch <input >output &&
1e2ae142 382 grep main output &&
472353a5
JK
383 grep branch output &&
384 ! grep m2 output &&
385 ! grep br2 output
ba959de1
SC
386'
387
019678d6 388test_expect_success 'ending prompt input with EOF' '
25098690 389 git difftool -x cat branch </dev/null >output &&
1e2ae142 390 ! grep main output &&
25098690
JS
391 ! grep branch output &&
392 ! grep m2 output &&
393 ! grep br2 output
394'
395
019678d6 396test_expect_success 'difftool --tool-help' '
e42360c4 397 git difftool --tool-help >output &&
472353a5 398 grep tool output
bf73fc21
TH
399'
400
019678d6 401test_expect_success 'setup change in subdirectory' '
1e2ae142 402 git checkout main &&
7e0abcec 403 mkdir sub &&
1e2ae142 404 echo main >sub/sub &&
7e0abcec
TH
405 git add sub/sub &&
406 git commit -m "added sub/sub" &&
853e10c1 407 git tag v1 &&
7e0abcec
TH
408 echo test >>file &&
409 echo test >>sub/sub &&
3caf5a93 410 git add file sub/sub &&
7e0abcec
TH
411 git commit -m "modified both"
412'
413
882add13
JS
414test_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
e01afdb7 433run_dir_diff_test () {
019678d6 434 test_expect_success "$1 --no-symlinks" "
e01afdb7
JK
435 symlinks=--no-symlinks &&
436 $2
437 "
019678d6 438 test_expect_success SYMLINKS "$1 --symlinks" "
e01afdb7
JK
439 symlinks=--symlinks &&
440 $2
441 "
442}
443
444run_dir_diff_test 'difftool -d' '
445 git difftool -d $symlinks --extcmd ls branch >output &&
e3f5da7e
SG
446 grep "^sub$" output &&
447 grep "^file$" output
7e0abcec
TH
448'
449
e01afdb7
JK
450run_dir_diff_test 'difftool --dir-diff' '
451 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
e3f5da7e
SG
452 grep "^sub$" output &&
453 grep "^file$" output
7e0abcec
TH
454'
455
4ac9f154
DA
456run_dir_diff_test 'difftool --dir-diff avoids repeated slashes in TMPDIR' '
457 TMPDIR="${TMPDIR:-/tmp}////" \
458 git difftool --dir-diff $symlinks --extcmd echo branch >output &&
459 grep -v // output >actual &&
460 test_line_count = 1 actual
461'
462
e01afdb7
JK
463run_dir_diff_test 'difftool --dir-diff ignores --prompt' '
464 git difftool --dir-diff $symlinks --prompt --extcmd ls branch >output &&
e3f5da7e
SG
465 grep "^sub$" output &&
466 grep "^file$" output
bf341b90
JK
467'
468
853e10c1 469run_dir_diff_test 'difftool --dir-diff branch from subdirectory' '
bf341b90
JK
470 (
471 cd sub &&
e01afdb7 472 git difftool --dir-diff $symlinks --extcmd ls branch >output &&
853e10c1
DA
473 # "sub" must only exist in "right"
474 # "file" and "file2" must be listed in both "left" and "right"
e3f5da7e 475 grep "^sub$" output >sub-output &&
1ce515f0 476 test_line_count = 1 sub-output &&
e3f5da7e 477 grep "^file$" output >file-output &&
1ce515f0 478 test_line_count = 2 file-output &&
e3f5da7e 479 grep "^file2$" output >file2-output &&
1ce515f0 480 test_line_count = 2 file2-output
853e10c1
DA
481 )
482'
483
484run_dir_diff_test 'difftool --dir-diff v1 from subdirectory' '
485 (
486 cd sub &&
487 git difftool --dir-diff $symlinks --extcmd ls v1 >output &&
488 # "sub" and "file" exist in both v1 and HEAD.
489 # "file2" is unchanged.
e3f5da7e 490 grep "^sub$" output >sub-output &&
1ce515f0 491 test_line_count = 2 sub-output &&
e3f5da7e 492 grep "^file$" output >file-output &&
1ce515f0 493 test_line_count = 2 file-output &&
e3f5da7e 494 ! grep "^file2$" output
853e10c1
DA
495 )
496'
497
498run_dir_diff_test 'difftool --dir-diff branch from subdirectory w/ pathspec' '
499 (
500 cd sub &&
501 git difftool --dir-diff $symlinks --extcmd ls branch -- .>output &&
502 # "sub" only exists in "right"
503 # "file" and "file2" must not be listed
e3f5da7e 504 grep "^sub$" output >sub-output &&
1ce515f0 505 test_line_count = 1 sub-output &&
e3f5da7e 506 ! grep "^file$" output
853e10c1
DA
507 )
508'
509
510run_dir_diff_test 'difftool --dir-diff v1 from subdirectory w/ pathspec' '
511 (
512 cd sub &&
513 git difftool --dir-diff $symlinks --extcmd ls v1 -- .>output &&
514 # "sub" exists in v1 and HEAD
515 # "file" is filtered out by the pathspec
e3f5da7e 516 grep "^sub$" output >sub-output &&
1ce515f0 517 test_line_count = 2 sub-output &&
e3f5da7e 518 ! grep "^file$" output
bf341b90
JK
519 )
520'
521
98f917ed
DA
522run_dir_diff_test 'difftool --dir-diff from subdirectory with GIT_DIR set' '
523 (
524 GIT_DIR=$(pwd)/.git &&
525 export GIT_DIR &&
526 GIT_WORK_TREE=$(pwd) &&
527 export GIT_WORK_TREE &&
528 cd sub &&
529 git difftool --dir-diff $symlinks --extcmd ls \
530 branch -- sub >output &&
e3f5da7e
SG
531 grep "^sub$" output &&
532 ! grep "^file$" output
98f917ed
DA
533 )
534'
535
1f197a1d
JK
536run_dir_diff_test 'difftool --dir-diff when worktree file is missing' '
537 test_when_finished git reset --hard &&
538 rm file2 &&
1e2ae142 539 git difftool --dir-diff $symlinks --extcmd ls branch main >output &&
e3f5da7e 540 grep "^file2$" output
1f197a1d
JK
541'
542
366f9cea
DA
543run_dir_diff_test 'difftool --dir-diff with unmerged files' '
544 test_when_finished git reset --hard &&
545 test_config difftool.echo.cmd "echo ok" &&
546 git checkout -B conflict-a &&
547 git checkout -B conflict-b &&
548 git checkout conflict-a &&
549 echo a >>file &&
550 git add file &&
551 git commit -m conflict-a &&
552 git checkout conflict-b &&
553 echo b >>file &&
554 git add file &&
555 git commit -m conflict-b &&
1e2ae142 556 git checkout main &&
366f9cea
DA
557 git merge conflict-a &&
558 test_must_fail git merge conflict-b &&
559 cat >expect <<-EOF &&
560 ok
561 EOF
562 git difftool --dir-diff $symlinks -t echo >actual &&
563 test_cmp expect actual
564'
565
02c56314
JK
566write_script .git/CHECK_SYMLINKS <<\EOF
567for f in file file2 sub/sub
568do
569 echo "$f"
d2addc3b 570 ls -ld "$2/$f" | sed -e 's/.* -> //'
02c56314
JK
571done >actual
572EOF
573
baa4adc6 574test_expect_success SYMLINKS 'difftool --dir-diff --symlinks without unstaged changes' '
02c56314
JK
575 cat >expect <<-EOF &&
576 file
fd318a94 577 $PWD/file
02c56314 578 file2
fd318a94 579 $PWD/file2
02c56314 580 sub/sub
fd318a94 581 $PWD/sub/sub
02c56314 582 EOF
baa4adc6 583 git difftool --dir-diff --symlinks \
02c56314 584 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
dcbaa0b3 585 test_cmp expect actual
02c56314
JK
586'
587
32eaf1de
KS
588write_script modify-right-file <<\EOF
589echo "new content" >"$2/file"
590EOF
591
592run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
593 test_when_finished git reset --hard &&
594 echo "orig content" >file &&
fd318a94 595 git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
32eaf1de
KS
596 echo "new content" >expect &&
597 test_cmp expect file
598'
599
600run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
601 test_when_finished git reset --hard &&
fd318a94 602 git difftool -d $symlinks --extcmd "$PWD/modify-right-file" branch &&
32eaf1de
KS
603 echo "new content" >expect &&
604 test_cmp expect file
605'
606
67aa147a
JK
607write_script modify-file <<\EOF
608echo "new content" >file
609EOF
610
019678d6 611test_expect_success 'difftool --no-symlinks does not overwrite working tree file ' '
67aa147a 612 echo "orig content" >file &&
fd318a94 613 git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-file" branch &&
67aa147a
JK
614 echo "new content" >expect &&
615 test_cmp expect file
616'
617
618write_script modify-both-files <<\EOF
619echo "wt content" >file &&
620echo "tmp content" >"$2/file" &&
621echo "$2" >tmpdir
622EOF
623
019678d6 624test_expect_success 'difftool --no-symlinks detects conflict ' '
67aa147a
JK
625 (
626 TMPDIR=$TRASH_DIRECTORY &&
627 export TMPDIR &&
628 echo "orig content" >file &&
fd318a94 629 test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$PWD/modify-both-files" branch &&
67aa147a
JK
630 echo "wt content" >expect &&
631 test_cmp expect file &&
632 echo "tmp content" >expect &&
633 test_cmp expect "$(cat tmpdir)/file"
634 )
635'
636
019678d6 637test_expect_success 'difftool properly honors gitlink and core.worktree' '
98fde5e4 638 test_when_finished rm -rf submod/ule &&
fcfec8bd 639 git submodule add ./. submod/ule &&
da568b66
JK
640 test_config -C submod/ule diff.tool checktrees &&
641 test_config -C submod/ule difftool.checktrees.cmd '\''
642 test -d "$LOCAL" && test -d "$REMOTE" && echo good
643 '\'' &&
fcfec8bd
JH
644 (
645 cd submod/ule &&
fcfec8bd
JH
646 echo good >expect &&
647 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
98fde5e4
DA
648 test_cmp expect actual &&
649 rm -f expect actual
fcfec8bd
JH
650 )
651'
652
019678d6 653test_expect_success SYMLINKS 'difftool --dir-diff symlinked directories' '
98fde5e4 654 test_when_finished git reset --hard &&
cfe2d4be
DA
655 git init dirlinks &&
656 (
657 cd dirlinks &&
658 git config diff.tool checktrees &&
659 git config difftool.checktrees.cmd "echo good" &&
660 mkdir foo &&
661 : >foo/bar &&
662 git add foo/bar &&
663 test_commit symlink-one &&
664 ln -s foo link &&
665 git add link &&
666 test_commit symlink-two &&
667 echo good >expect &&
668 git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
669 test_cmp expect actual
670 )
671'
672
18ec8005
DA
673test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
674 test_when_finished git reset --hard &&
675 touch b &&
676 ln -s b c &&
677 git add b c &&
678 test_tick &&
679 git commit -m initial &&
680 touch d &&
681 rm c &&
682 ln -s d c &&
683 cat >expect <<-EOF &&
18ec8005
DA
684 c
685
686 c
687 EOF
688 git difftool --symlinks --dir-diff --extcmd ls >output &&
689 grep -v ^/ output >actual &&
690 test_cmp expect actual &&
691
692 git difftool --no-symlinks --dir-diff --extcmd ls >output &&
693 grep -v ^/ output >actual &&
694 test_cmp expect actual &&
695
696 # The left side contains symlink "c" that points to "b"
697 test_config difftool.cat.cmd "cat \$LOCAL/c" &&
698 printf "%s\n" b >expect &&
699
700 git difftool --symlinks --dir-diff --tool cat >actual &&
701 test_cmp expect actual &&
702
703 git difftool --symlinks --no-symlinks --dir-diff --tool cat >actual &&
704 test_cmp expect actual &&
705
706 # The right side contains symlink "c" that points to "d"
707 test_config difftool.cat.cmd "cat \$REMOTE/c" &&
708 printf "%s\n" d >expect &&
709
710 git difftool --symlinks --dir-diff --tool cat >actual &&
711 test_cmp expect actual &&
712
713 git difftool --no-symlinks --dir-diff --tool cat >actual &&
714 test_cmp expect actual &&
715
716 # Deleted symlinks
717 rm -f c &&
718 cat >expect <<-EOF &&
18ec8005
DA
719 c
720
721 EOF
722 git difftool --symlinks --dir-diff --extcmd ls >output &&
723 grep -v ^/ output >actual &&
724 test_cmp expect actual &&
725
726 git difftool --no-symlinks --dir-diff --extcmd ls >output &&
727 grep -v ^/ output >actual &&
728 test_cmp expect actual
729'
730
5bafb357
DA
731test_expect_success SYMLINKS 'difftool --dir-diff writes symlinks as raw text' '
732 # Start out on a branch called "branch-init".
733 git init -b branch-init symlink-files &&
734 (
735 cd symlink-files &&
736 # This test ensures that symlinks are written as raw text.
737 # The "cat" tools output link and file contents.
738 git config difftool.cat-left-link.cmd "cat \"\$LOCAL/link\"" &&
739 git config difftool.cat-left-a.cmd "cat \"\$LOCAL/file-a\"" &&
740 git config difftool.cat-right-link.cmd "cat \"\$REMOTE/link\"" &&
741 git config difftool.cat-right-b.cmd "cat \"\$REMOTE/file-b\"" &&
742
743 # Record the empty initial state so that we can come back here
744 # later and not have to consider the any cases where difftool
745 # will create symlinks back into the worktree.
746 test_tick &&
747 git commit --allow-empty -m init &&
748
749 # Create a file called "file-a" with a symlink pointing to it.
750 git switch -c branch-a &&
751 echo a >file-a &&
752 ln -s file-a link &&
753 git add file-a link &&
754 test_tick &&
755 git commit -m link-to-file-a &&
756
757 # Create a file called "file-b" and point the symlink to it.
758 git switch -c branch-b &&
759 echo b >file-b &&
760 rm link &&
761 ln -s file-b link &&
762 git add file-b link &&
763 git rm file-a &&
764 test_tick &&
765 git commit -m link-to-file-b &&
766
767 # Checkout the initial branch so that the --symlinks behavior is
768 # not activated. The two directories should be completely
769 # independent with no symlinks pointing back here.
770 git switch branch-init &&
771
772 # The left link must be "file-a" and "file-a" must contain "a".
773 echo file-a >expect &&
774 git difftool --symlinks --dir-diff --tool cat-left-link \
775 branch-a branch-b >actual &&
776 test_cmp expect actual &&
777
778 echo a >expect &&
779 git difftool --symlinks --dir-diff --tool cat-left-a \
780 branch-a branch-b >actual &&
781 test_cmp expect actual &&
782
783 # The right link must be "file-b" and "file-b" must contain "b".
784 echo file-b >expect &&
785 git difftool --symlinks --dir-diff --tool cat-right-link \
786 branch-a branch-b >actual &&
787 test_cmp expect actual &&
788
789 echo b >expect &&
790 git difftool --symlinks --dir-diff --tool cat-right-b \
791 branch-a branch-b >actual &&
792 test_cmp expect actual
793 )
794'
795
3080c509
JS
796test_expect_success 'add -N and difftool -d' '
797 test_when_finished git reset --hard &&
798
799 test_write_lines A B C >intent-to-add &&
800 git add -N intent-to-add &&
801 git difftool --dir-diff --extcmd ls
802'
803
24695934
JK
804test_expect_success 'difftool --cached with unmerged files' '
805 test_when_finished git reset --hard &&
d6685180
JK
806
807 test_commit conflicting &&
808 test_commit conflict-a conflict.t a &&
809 git reset --hard conflicting &&
810 test_commit conflict-b conflict.t b &&
811 test_must_fail git merge conflict-a &&
812
813 git difftool --cached --no-prompt >output &&
814 test_must_be_empty output
24695934
JK
815'
816
20de316e
JS
817test_expect_success 'outside worktree' '
818 echo 1 >1 &&
819 echo 2 >2 &&
820 test_expect_code 1 nongit git \
821 -c diff.tool=echo -c difftool.echo.cmd="echo \$LOCAL \$REMOTE" \
822 difftool --no-prompt --no-index ../1 ../2 >actual &&
823 echo "../1 ../2" >expect &&
824 test_cmp expect actual
825'
826
7f978d7d
DL
827test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive' '
828 difftool_test_setup &&
829 test_must_fail git difftool --gui --tool=test-tool &&
830 test_must_fail git difftool --gui --extcmd=cat &&
831 test_must_fail git difftool --tool=test-tool --extcmd=cat &&
832 test_must_fail git difftool --gui --tool=test-tool --extcmd=cat
833'
834
1c881026
ZH
835test_expect_success 'difftool --rotate-to' '
836 difftool_test_setup &&
837 test_when_finished git reset --hard &&
838 echo 1 >1 &&
839 echo 2 >2 &&
840 echo 4 >4 &&
841 git add 1 2 4 &&
842 git commit -a -m "124" &&
52ff891c 843 git difftool --no-prompt --extcmd=cat --rotate-to="2" HEAD^ >output &&
1c881026
ZH
844 cat >expect <<-\EOF &&
845 2
846 4
847 1
848 EOF
849 test_cmp output expect
850'
851
852test_expect_success 'difftool --skip-to' '
853 difftool_test_setup &&
854 test_when_finished git reset --hard &&
855 git difftool --no-prompt --extcmd=cat --skip-to="2" HEAD^ >output &&
856 cat >expect <<-\EOF &&
857 2
858 4
859 EOF
860 test_cmp output expect
861'
862
863test_expect_success 'difftool --rotate/skip-to error condition' '
864 test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^ &&
865 test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
866'
f92f2038 867test_done