1#!/bin/sh
2#
3# Copyright (c) 2009, 2010, 2012, 2013 David Aguilar
4#
5
6test_description='git-difftool
7
8Testing basic diff tool invocation
9'
10
11. ./test-lib.sh
12
13difftool_test_setup ()
14{
15 test_config diff.tool test-tool &&
16 test_config difftool.test-tool.cmd 'cat "$LOCAL"' &&
17 test_config difftool.bogus-tool.cmd false
18}
19
20prompt_given ()
21{
22 prompt="$1"
23 test "$prompt" = "Launch 'test-tool' [Y/n]: branch"
24}
25
26stdin_contains ()
27{
28 grep >/dev/null "$1"
29}
30
31stdin_doesnot_contain ()
32{
33 ! stdin_contains "$1"
34}
35
36# Create a file on master and change it on branch
37test_expect_success PERL 'setup' '
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
49test_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 &&
55
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
60'
61
62test_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
67'
68
69test_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
74'
75
76test_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
87'
88
89test_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 &&
94
95 echo branch >expect &&
96 git difftool --no-prompt --gui branch >actual &&
97 test_cmp expect actual
98'
99
100test_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 &&
105
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
112'
113
114test_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
119'
120
121# Specify the diff tool using $GIT_DIFF_TOOL
122test_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
128'
129
130# Test the $GIT_*_TOOL variables and ensure
131# that $GIT_DIFF_TOOL always wins unless --tool is specified
132test_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 &&
136
137 echo branch >expect &&
138 GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual &&
139 test_cmp expect actual &&
140
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
146'
147
148# Test that we don't have to pass --no-prompt to difftool
149# when $GIT_DIFFTOOL_NO_PROMPT is true
150test_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
155'
156
157# git-difftool supports the difftool.prompt variable.
158# Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false
159test_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"
166'
167
168# Test that we don't have to pass --no-prompt when difftool.prompt is false
169test_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
175'
176
177# Test that we don't have to pass --no-prompt when mergetool.prompt is false
178test_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
185'
186
187# Test that the -y flag can override difftool.prompt = true
188test_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
194'
195
196# Test that the --prompt flag can override difftool.prompt = false
197test_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"
204'
205
206# Test that the last flag passed on the command-line wins
207test_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"
216'
217
218# git-difftool falls back to git-mergetool config variables
219# so test that behavior here
220test_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 &&
226
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
232'
233
234test_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
239'
240
241test_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
246'
247
248test_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
253'
254
255test_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
260'
261
262test_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
267'
268
269test_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
274'
275
276test_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
281'
282
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' '
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
303'
304
305test_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
312'
313
314test_expect_success PERL 'difftool --tool-help' '
315 git difftool --tool-help >output &&
316 stdin_contains tool <output
317'
318
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' '
332 git difftool -d --extcmd ls branch >output &&
333 stdin_contains sub <output &&
334 stdin_contains file <output
335'
336
337test_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
341'
342
343write_script .git/CHECK_SYMLINKS <<\EOF
344for f in file file2 sub/sub
345do
346 echo "$f"
347 readlink "$2/$f"
348done >actual
349EOF
350
351test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' '
352 cat >expect <<-EOF &&
353 file
354 $(pwd)/file
355 file2
356 $(pwd)/file2
357 sub/sub
358 $(pwd)/sub/sub
359 EOF
360 git difftool --dir-diff --symlink \
361 --extcmd "./.git/CHECK_SYMLINKS" branch HEAD &&
362 test_cmp actual expect
363'
364
365test_expect_success PERL 'difftool --dir-diff ignores --prompt' '
366 git difftool --dir-diff --prompt --extcmd ls branch >output &&
367 stdin_contains sub <output &&
368 stdin_contains file <output
369'
370
371test_expect_success PERL 'difftool --dir-diff from subdirectory' '
372 (
373 cd sub &&
374 git difftool --dir-diff --extcmd ls branch >output &&
375 stdin_contains sub <output &&
376 stdin_contains file <output
377 )
378'
379
380test_done