difftool: don't overwrite modified files
[git.git] / t / t7800-difftool.sh
blob017f55adf4d88c3e550812388d29b7a9a4d9db3d
1 #!/bin/sh
3 # Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
6 test_description='git-difftool
8 Testing basic diff tool invocation
11 . ./test-lib.sh
13 difftool_test_setup ()
15 test_config diff.tool test-tool &&
16 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
17 test_config difftool.bogus-tool.cmd false
20 prompt_given ()
22 prompt="$1"
23 test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
26 stdin_contains ()
28 grep >/dev/null "$1"
31 stdin_doesnot_contain ()
33 ! stdin_contains "$1"
36 # Create a file on master and change it on branch
37 test_expect_success PERL 'setup' '
38 echo master >file &&
39 git add file &&
40 git commit -m "added file" &&
42 git checkout -b branch master &&
43 echo branch >file &&
44 git commit -a -m "branch changed file" &&
45 git checkout master
48 # Configure a custom difftool.<tool>.cmd and use it
49 test_expect_success PERL 'custom commands' '
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 &&
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
62 test_expect_success PERL 'custom tool commands override built-ins' '
63 test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" &&
64 echo master >expect &&
65 git difftool --tool vimdiff --no-prompt branch >actual &&
66 test_cmp expect actual
69 test_expect_success PERL 'difftool ignores bad --tool values' '
70 : >expect &&
71 test_expect_code 1 \
72 git difftool --no-prompt --tool=bad-tool branch >actual &&
73 test_cmp expect actual
76 test_expect_success PERL 'difftool forwards arguments to diff' '
77 difftool_test_setup &&
78 >for-diff &&
79 git add for-diff &&
80 echo changes>for-diff &&
81 git add for-diff &&
82 : >expect &&
83 git difftool --cached --no-prompt -- for-diff >actual &&
84 test_cmp expect actual &&
85 git reset -- for-diff &&
86 rm for-diff
89 test_expect_success PERL 'difftool honors --gui' '
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 &&
95 echo branch >expect &&
96 git difftool --no-prompt --gui branch >actual &&
97 test_cmp expect actual
100 test_expect_success PERL 'difftool --gui last setting wins' '
101 difftool_test_setup &&
102 : >expect &&
103 git difftool --no-prompt --gui --no-gui >actual &&
104 test_cmp expect actual &&
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
114 test_expect_success PERL 'difftool --gui works without configured diff.guitool' '
115 difftool_test_setup &&
116 echo branch >expect &&
117 git difftool --no-prompt --gui branch >actual &&
118 test_cmp expect actual
121 # Specify the diff tool using $GIT_DIFF_TOOL
122 test_expect_success PERL 'GIT_DIFF_TOOL variable' '
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
130 # Test the $GIT_*_TOOL variables and ensure
131 # that $GIT_DIFF_TOOL always wins unless --tool is specified
132 test_expect_success PERL 'GIT_DIFF_TOOL overrides' '
133 difftool_test_setup &&
134 test_config diff.tool bogus-tool &&
135 test_config merge.tool bogus-tool &&
137 echo branch >expect &&
138 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
139 test_cmp expect actual &&
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
148 # Test that we don't have to pass --no-prompt to difftool
149 # when $GIT_DIFFTOOL_NO_PROMPT is true
150 test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' '
151 difftool_test_setup &&
152 echo branch >expect &&
153 GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual &&
154 test_cmp expect actual
157 # git-difftool supports the difftool.prompt variable.
158 # Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
159 test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' '
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"
168 # Test that we don't have to pass --no-prompt when difftool.prompt is false
169 test_expect_success PERL 'difftool.prompt config variable is false' '
170 difftool_test_setup &&
171 test_config difftool.prompt false &&
172 echo branch >expect &&
173 git difftool branch >actual &&
174 test_cmp expect actual
177 # Test that we don't have to pass --no-prompt when mergetool.prompt is false
178 test_expect_success PERL 'difftool merge.prompt = false' '
179 difftool_test_setup &&
180 test_might_fail git config --unset difftool.prompt &&
181 test_config mergetool.prompt false &&
182 echo branch >expect &&
183 git difftool branch >actual &&
184 test_cmp expect actual
187 # Test that the -y flag can override difftool.prompt = true
188 test_expect_success PERL 'difftool.prompt can overridden with -y' '
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
196 # Test that the --prompt flag can override difftool.prompt = false
197 test_expect_success PERL 'difftool.prompt can overridden with --prompt' '
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"
206 # Test that the last flag passed on the command-line wins
207 test_expect_success PERL 'difftool last flag wins' '
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"
218 # git-difftool falls back to git-mergetool config variables
219 # so test that behavior here
220 test_expect_success PERL 'difftool + mergetool config variables' '
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 &&
227 # set merge.tool to something bogus, diff.tool to test-tool
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
234 test_expect_success PERL 'difftool.<tool>.path' '
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
241 test_expect_success PERL 'difftool --extcmd=cat' '
242 echo branch >expect &&
243 echo master >>expect &&
244 git difftool --no-prompt --extcmd=cat branch >actual &&
245 test_cmp expect actual
248 test_expect_success PERL 'difftool --extcmd cat' '
249 echo branch >expect &&
250 echo master >>expect &&
251 git difftool --no-prompt --extcmd=cat branch >actual &&
252 test_cmp expect actual
255 test_expect_success PERL 'difftool -x cat' '
256 echo branch >expect &&
257 echo master >>expect &&
258 git difftool --no-prompt -x cat branch >actual &&
259 test_cmp expect actual
262 test_expect_success PERL 'difftool --extcmd echo arg1' '
263 echo file >expect &&
264 git difftool --no-prompt \
265 --extcmd sh\ -c\ \"echo\ \$1\" branch >actual &&
266 test_cmp expect actual
269 test_expect_success PERL 'difftool --extcmd cat arg1' '
270 echo master >expect &&
271 git difftool --no-prompt \
272 --extcmd sh\ -c\ \"cat\ \$1\" branch >actual &&
273 test_cmp expect actual
276 test_expect_success PERL 'difftool --extcmd cat arg2' '
277 echo branch >expect &&
278 git difftool --no-prompt \
279 --extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
280 test_cmp expect actual
283 # Create a second file on master and a different version on branch
284 test_expect_success PERL 'setup with 2 files different' '
285 echo m2 >file2 &&
286 git add file2 &&
287 git commit -m "added file2" &&
289 git checkout branch &&
290 echo br2 >file2 &&
291 git add file2 &&
292 git commit -a -m "branch changed file2" &&
293 git checkout master
296 test_expect_success PERL 'say no to the first file' '
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
305 test_expect_success PERL 'say no to the second file' '
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
314 test_expect_success PERL 'difftool --tool-help' '
315 git difftool --tool-help >output &&
316 stdin_contains tool <output
319 test_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"
331 test_expect_success PERL 'difftool -d' '
332 git difftool -d --extcmd ls branch >output &&
333 stdin_contains sub <output &&
334 stdin_contains file <output
337 test_expect_success PERL 'difftool --dir-diff' '
338 git difftool --dir-diff --extcmd ls branch >output &&
339 stdin_contains sub <output &&
340 stdin_contains file <output
343 test_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
349 test_expect_success PERL 'difftool --dir-diff from subdirectory' '
351 cd sub &&
352 git difftool --dir-diff --extcmd ls branch >output &&
353 stdin_contains sub <output &&
354 stdin_contains file <output
358 write_script .git/CHECK_SYMLINKS <<\EOF
359 for f in file file2 sub/sub
361 echo "$f"
362 readlink "$2/$f"
363 done >actual
366 test_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
375 git difftool --dir-diff --symlink \
376 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
377 test_cmp actual expect
380 write_script modify-file <<\EOF
381 echo "new content" >file
384 test_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
391 write_script modify-both-files <<\EOF
392 echo "wt content" >file &&
393 echo "tmp content" >"$2/file" &&
394 echo "$2" >tmpdir
397 test_expect_success PERL 'difftool --no-symlinks detects conflict ' '
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"
410 test_done