]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7800-difftool.sh
difftool: don't overwrite modified files
[thirdparty/git.git] / t / t7800-difftool.sh
CommitLineData
f92f2038
DA
1#!/bin/sh
2#
9e5a86f2 3# Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
f92f2038
DA
4#
5
6test_description='git-difftool
7
8Testing basic diff tool invocation
9'
10
11. ./test-lib.sh
12
e42360c4 13difftool_test_setup ()
f92f2038 14{
e42360c4
DA
15 test_config diff.tool test-tool &&
16 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
17 test_config difftool.bogus-tool.cmd false
f92f2038
DA
18}
19
e42360c4 20prompt_given ()
a904392e
DA
21{
22 prompt="$1"
ba959de1
SC
23 test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
24}
25
e42360c4 26stdin_contains ()
ba959de1
SC
27{
28 grep >/dev/null "$1"
29}
30
e42360c4 31stdin_doesnot_contain ()
ba959de1
SC
32{
33 ! stdin_contains "$1"
a904392e
DA
34}
35
f92f2038 36# Create a file on master and change it on branch
2c4f3026 37test_expect_success PERL 'setup' '
f92f2038
DA
38 echo master >file &&
39 git add file &&
40 git commit -m "added file" &&
41
42 git checkout -b branch master &&
43 echo branch >file &&
44 git commit -a -m "branch changed file" &&
45 git checkout master
46'
47
48# Configure a custom difftool.<tool>.cmd and use it
2c4f3026 49test_expect_success PERL 'custom commands' '
e42360c4
DA
50 difftool_test_setup &&
51 test_config difftool.test-tool.cmd "cat \"\$REMOTE\"" &&
52 echo master >expect &&
53 git difftool --no-prompt branch >actual &&
54 test_cmp expect actual &&
f92f2038 55
e42360c4
DA
56 test_config difftool.test-tool.cmd "cat \"\$LOCAL\"" &&
57 echo branch >expect &&
58 git difftool --no-prompt branch >actual &&
59 test_cmp expect actual
f92f2038
DA
60'
61
e42360c4 62test_expect_success PERL 'custom tool commands override built-ins' '
f469e840 63 test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" &&
e42360c4 64 echo master >expect &&
f469e840 65 git difftool --tool vimdiff --no-prompt branch >actual &&
e42360c4 66 test_cmp expect actual
a427ef7a
DA
67'
68
2c4f3026 69test_expect_success PERL 'difftool ignores bad --tool values' '
e42360c4
DA
70 : >expect &&
71 test_expect_code 1 \
72 git difftool --no-prompt --tool=bad-tool branch >actual &&
73 test_cmp expect actual
f92f2038
DA
74'
75
d50b2c73 76test_expect_success PERL 'difftool forwards arguments to diff' '
e42360c4 77 difftool_test_setup &&
d50b2c73
DA
78 >for-diff &&
79 git add for-diff &&
80 echo changes>for-diff &&
81 git add for-diff &&
e42360c4
DA
82 : >expect &&
83 git difftool --cached --no-prompt -- for-diff >actual &&
84 test_cmp expect actual &&
d50b2c73
DA
85 git reset -- for-diff &&
86 rm for-diff
87'
88
2c4f3026 89test_expect_success PERL 'difftool honors --gui' '
e42360c4
DA
90 difftool_test_setup &&
91 test_config merge.tool bogus-tool &&
92 test_config diff.tool bogus-tool &&
93 test_config diff.guitool test-tool &&
4cefa495 94
e42360c4
DA
95 echo branch >expect &&
96 git difftool --no-prompt --gui branch >actual &&
97 test_cmp expect actual
4cefa495
DA
98'
99
85089604 100test_expect_success PERL 'difftool --gui last setting wins' '
e42360c4
DA
101 difftool_test_setup &&
102 : >expect &&
103 git difftool --no-prompt --gui --no-gui >actual &&
104 test_cmp expect actual &&
85089604 105
e42360c4
DA
106 test_config merge.tool bogus-tool &&
107 test_config diff.tool bogus-tool &&
108 test_config diff.guitool test-tool &&
109 echo branch >expect &&
110 git difftool --no-prompt --no-gui --gui branch >actual &&
111 test_cmp expect actual
85089604
TH
112'
113
2c4f3026 114test_expect_success PERL 'difftool --gui works without configured diff.guitool' '
e42360c4
DA
115 difftool_test_setup &&
116 echo branch >expect &&
117 git difftool --no-prompt --gui branch >actual &&
118 test_cmp expect actual
42accaec
DA
119'
120
f92f2038 121# Specify the diff tool using $GIT_DIFF_TOOL
2c4f3026 122test_expect_success PERL 'GIT_DIFF_TOOL variable' '
e42360c4
DA
123 difftool_test_setup &&
124 git config --unset diff.tool &&
125 echo branch >expect &&
126 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
127 test_cmp expect actual
f92f2038
DA
128'
129
130# Test the $GIT_*_TOOL variables and ensure
131# that $GIT_DIFF_TOOL always wins unless --tool is specified
2c4f3026 132test_expect_success PERL 'GIT_DIFF_TOOL overrides' '
e42360c4
DA
133 difftool_test_setup &&
134 test_config diff.tool bogus-tool &&
135 test_config merge.tool bogus-tool &&
f92f2038 136
e42360c4
DA
137 echo branch >expect &&
138 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
139 test_cmp expect actual &&
f92f2038 140
e42360c4
DA
141 test_config diff.tool bogus-tool &&
142 test_config merge.tool bogus-tool &&
143 GIT_DIFF_TOOL=bogus-tool \
144 git difftool --no-prompt --tool=test-tool branch >actual &&
145 test_cmp expect actual
f92f2038
DA
146'
147
148# Test that we don't have to pass --no-prompt to difftool
149# when $GIT_DIFFTOOL_NO_PROMPT is true
2c4f3026 150test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' '
e42360c4
DA
151 difftool_test_setup &&
152 echo branch >expect &&
153 GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
154 test_cmp expect actual
f92f2038
DA
155'
156
a904392e
DA
157# git-difftool supports the difftool.prompt variable.
158# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
2c4f3026 159test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' '
e42360c4
DA
160 difftool_test_setup &&
161 test_config difftool.prompt false &&
162 echo >input &&
163 GIT_DIFFTOOL_PROMPT=true git difftool branch <input >output &&
164 prompt=$(tail -1 <output) &&
165 prompt_given "$prompt"
a904392e
DA
166'
167
168# Test that we don't have to pass --no-prompt when difftool.prompt is false
2c4f3026 169test_expect_success PERL 'difftool.prompt config variable is false' '
e42360c4
DA
170 difftool_test_setup &&
171 test_config difftool.prompt false &&
172 echo branch >expect &&
173 git difftool branch >actual &&
174 test_cmp expect actual
a904392e
DA
175'
176
a88183f1 177# Test that we don't have to pass --no-prompt when mergetool.prompt is false
2c4f3026 178test_expect_success PERL 'difftool merge.prompt = false' '
e42360c4 179 difftool_test_setup &&
bc0f35ca 180 test_might_fail git config --unset difftool.prompt &&
e42360c4
DA
181 test_config mergetool.prompt false &&
182 echo branch >expect &&
183 git difftool branch >actual &&
184 test_cmp expect actual
a88183f1
DA
185'
186
a904392e 187# Test that the -y flag can override difftool.prompt = true
2c4f3026 188test_expect_success PERL 'difftool.prompt can overridden with -y' '
e42360c4
DA
189 difftool_test_setup &&
190 test_config difftool.prompt true &&
191 echo branch >expect &&
192 git difftool -y branch >actual &&
193 test_cmp expect actual
a904392e
DA
194'
195
196# Test that the --prompt flag can override difftool.prompt = false
2c4f3026 197test_expect_success PERL 'difftool.prompt can overridden with --prompt' '
e42360c4
DA
198 difftool_test_setup &&
199 test_config difftool.prompt false &&
200 echo >input &&
201 git difftool --prompt branch <input >output &&
202 prompt=$(tail -1 <output) &&
203 prompt_given "$prompt"
a904392e
DA
204'
205
206# Test that the last flag passed on the command-line wins
2c4f3026 207test_expect_success PERL 'difftool last flag wins' '
e42360c4
DA
208 difftool_test_setup &&
209 echo branch >expect &&
210 git difftool --prompt --no-prompt branch >actual &&
211 test_cmp expect actual &&
212 echo >input &&
213 git difftool --no-prompt --prompt branch <input >output &&
214 prompt=$(tail -1 <output) &&
215 prompt_given "$prompt"
a904392e
DA
216'
217
f92f2038
DA
218# git-difftool falls back to git-mergetool config variables
219# so test that behavior here
2c4f3026 220test_expect_success PERL 'difftool + mergetool config variables' '
e42360c4
DA
221 test_config merge.tool test-tool &&
222 test_config mergetool.test-tool.cmd "cat \$LOCAL" &&
223 echo branch >expect &&
224 git difftool --no-prompt branch >actual &&
225 test_cmp expect actual &&
f92f2038
DA
226
227 # set merge.tool to something bogus, diff.tool to test-tool
e42360c4
DA
228 test_config merge.tool bogus-tool &&
229 test_config diff.tool test-tool &&
230 git difftool --no-prompt branch >actual &&
231 test_cmp expect actual
f92f2038
DA
232'
233
2c4f3026 234test_expect_success PERL 'difftool.<tool>.path' '
e42360c4
DA
235 test_config difftool.tkdiff.path echo &&
236 git difftool --tool=tkdiff --no-prompt branch >output &&
237 lines=$(grep file output | wc -l) &&
238 test "$lines" -eq 1
1c6f5b52
DA
239'
240
2c4f3026 241test_expect_success PERL 'difftool --extcmd=cat' '
e42360c4
DA
242 echo branch >expect &&
243 echo master >>expect &&
244 git difftool --no-prompt --extcmd=cat branch >actual &&
245 test_cmp expect actual
f47f1e2c 246'
1c6f5b52 247
2c4f3026 248test_expect_success PERL 'difftool --extcmd cat' '
e42360c4
DA
249 echo branch >expect &&
250 echo master >>expect &&
251 git difftool --no-prompt --extcmd=cat branch >actual &&
252 test_cmp expect actual
f47f1e2c 253'
1c6f5b52 254
2c4f3026 255test_expect_success PERL 'difftool -x cat' '
e42360c4
DA
256 echo branch >expect &&
257 echo master >>expect &&
258 git difftool --no-prompt -x cat branch >actual &&
259 test_cmp expect actual
9f3d54d1
DA
260'
261
2c4f3026 262test_expect_success PERL 'difftool --extcmd echo arg1' '
e42360c4
DA
263 echo file >expect &&
264 git difftool --no-prompt \
265 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
266 test_cmp expect actual
9f3d54d1 267'
1c6f5b52 268
2c4f3026 269test_expect_success PERL 'difftool --extcmd cat arg1' '
e42360c4
DA
270 echo master >expect &&
271 git difftool --no-prompt \
272 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
273 test_cmp expect actual
9f3d54d1 274'
1c6f5b52 275
2c4f3026 276test_expect_success PERL 'difftool --extcmd cat arg2' '
e42360c4
DA
277 echo branch >expect &&
278 git difftool --no-prompt \
279 --extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
280 test_cmp expect actual
f92f2038
DA
281'
282
ba959de1
SC
283# Create a second file on master and a different version on branch
284test_expect_success PERL 'setup with 2 files different' '
285 echo m2 >file2 &&
286 git add file2 &&
287 git commit -m "added file2" &&
288
289 git checkout branch &&
290 echo br2 >file2 &&
291 git add file2 &&
292 git commit -a -m "branch changed file2" &&
293 git checkout master
294'
295
296test_expect_success PERL 'say no to the first file' '
e42360c4
DA
297 (echo n && echo) >input &&
298 git difftool -x cat branch <input >output &&
299 stdin_contains m2 <output &&
300 stdin_contains br2 <output &&
301 stdin_doesnot_contain master <output &&
302 stdin_doesnot_contain branch <output
ba959de1
SC
303'
304
305test_expect_success PERL 'say no to the second file' '
e42360c4
DA
306 (echo && echo n) >input &&
307 git difftool -x cat branch <input >output &&
308 stdin_contains master <output &&
309 stdin_contains branch <output &&
310 stdin_doesnot_contain m2 <output &&
311 stdin_doesnot_contain br2 <output
ba959de1
SC
312'
313
bf73fc21 314test_expect_success PERL 'difftool --tool-help' '
e42360c4
DA
315 git difftool --tool-help >output &&
316 stdin_contains tool <output
bf73fc21
TH
317'
318
7e0abcec
TH
319test_expect_success PERL 'setup change in subdirectory' '
320 git checkout master &&
321 mkdir sub &&
322 echo master >sub/sub &&
323 git add sub/sub &&
324 git commit -m "added sub/sub" &&
325 echo test >>file &&
326 echo test >>sub/sub &&
327 git add . &&
328 git commit -m "modified both"
329'
330
331test_expect_success PERL 'difftool -d' '
e42360c4
DA
332 git difftool -d --extcmd ls branch >output &&
333 stdin_contains sub <output &&
334 stdin_contains file <output
7e0abcec
TH
335'
336
337test_expect_success PERL 'difftool --dir-diff' '
e42360c4
DA
338 git difftool --dir-diff --extcmd ls branch >output &&
339 stdin_contains sub <output &&
340 stdin_contains file <output
7e0abcec
TH
341'
342
bf341b90
JK
343test_expect_success PERL 'difftool --dir-diff ignores --prompt' '
344 git difftool --dir-diff --prompt --extcmd ls branch >output &&
345 stdin_contains sub <output &&
346 stdin_contains file <output
347'
348
349test_expect_success PERL 'difftool --dir-diff from subdirectory' '
350 (
351 cd sub &&
352 git difftool --dir-diff --extcmd ls branch >output &&
353 stdin_contains sub <output &&
354 stdin_contains file <output
355 )
356'
357
02c56314
JK
358write_script .git/CHECK_SYMLINKS <<\EOF
359for f in file file2 sub/sub
360do
361 echo "$f"
362 readlink "$2/$f"
363done >actual
364EOF
365
366test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' '
367 cat >expect <<-EOF &&
368 file
369 $(pwd)/file
370 file2
371 $(pwd)/file2
372 sub/sub
373 $(pwd)/sub/sub
374 EOF
375 git difftool --dir-diff --symlink \
376 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
377 test_cmp actual expect
378'
379
67aa147a
JK
380write_script modify-file <<\EOF
381echo "new content" >file
382EOF
383
384test_expect_success PERL 'difftool --no-symlinks does not overwrite working tree file ' '
385 echo "orig content" >file &&
386 git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-file" branch &&
387 echo "new content" >expect &&
388 test_cmp expect file
389'
390
391write_script modify-both-files <<\EOF
392echo "wt content" >file &&
393echo "tmp content" >"$2/file" &&
394echo "$2" >tmpdir
395EOF
396
397test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
398 (
399 TMPDIR=$TRASH_DIRECTORY &&
400 export TMPDIR &&
401 echo "orig content" >file &&
402 test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-both-files" branch &&
403 echo "wt content" >expect &&
404 test_cmp expect file &&
405 echo "tmp content" >expect &&
406 test_cmp expect "$(cat tmpdir)/file"
407 )
408'
409
f92f2038 410test_done