]> git.ipfire.org Git - thirdparty/git.git/blob - t/t4020-diff-external.sh
Merge branch 'en/fetch-negotiation-default-fix'
[thirdparty/git.git] / t / t4020-diff-external.sh
1 #!/bin/sh
2
3 test_description='external diff interface test'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success setup '
9
10 test_tick &&
11 echo initial >file &&
12 git add file &&
13 git commit -m initial &&
14
15 test_tick &&
16 echo second >file &&
17 before=$(git hash-object file) &&
18 before=$(git rev-parse --short $before) &&
19 git add file &&
20 git commit -m second &&
21
22 test_tick &&
23 echo third >file
24 '
25
26 test_expect_success 'GIT_EXTERNAL_DIFF environment' '
27
28 GIT_EXTERNAL_DIFF=echo git diff | {
29 read path oldfile oldhex oldmode newfile newhex newmode &&
30 test "z$path" = zfile &&
31 test "z$oldmode" = z100644 &&
32 test "z$newhex" = "z$ZERO_OID" &&
33 test "z$newmode" = z100644 &&
34 oh=$(git rev-parse --verify HEAD:file) &&
35 test "z$oh" = "z$oldhex"
36 }
37
38 '
39
40 test_expect_success 'GIT_EXTERNAL_DIFF environment should apply only to diff' '
41
42 GIT_EXTERNAL_DIFF=echo git log -p -1 HEAD |
43 grep "^diff --git a/file b/file"
44
45 '
46
47 test_expect_success 'GIT_EXTERNAL_DIFF environment and --no-ext-diff' '
48
49 GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff |
50 grep "^diff --git a/file b/file"
51
52 '
53
54 test_expect_success SYMLINKS 'typechange diff' '
55 rm -f file &&
56 ln -s elif file &&
57 GIT_EXTERNAL_DIFF=echo git diff | {
58 read path oldfile oldhex oldmode newfile newhex newmode &&
59 test "z$path" = zfile &&
60 test "z$oldmode" = z100644 &&
61 test "z$newhex" = "z$ZERO_OID" &&
62 test "z$newmode" = z120000 &&
63 oh=$(git rev-parse --verify HEAD:file) &&
64 test "z$oh" = "z$oldhex"
65 } &&
66 GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff >actual &&
67 git diff >expect &&
68 test_cmp expect actual
69 '
70
71 test_expect_success 'diff.external' '
72 git reset --hard &&
73 echo third >file &&
74 test_config diff.external echo &&
75 git diff | {
76 read path oldfile oldhex oldmode newfile newhex newmode &&
77 test "z$path" = zfile &&
78 test "z$oldmode" = z100644 &&
79 test "z$newhex" = "z$ZERO_OID" &&
80 test "z$newmode" = z100644 &&
81 oh=$(git rev-parse --verify HEAD:file) &&
82 test "z$oh" = "z$oldhex"
83 }
84 '
85
86 test_expect_success 'diff.external should apply only to diff' '
87 test_config diff.external echo &&
88 git log -p -1 HEAD |
89 grep "^diff --git a/file b/file"
90 '
91
92 test_expect_success 'diff.external and --no-ext-diff' '
93 test_config diff.external echo &&
94 git diff --no-ext-diff |
95 grep "^diff --git a/file b/file"
96 '
97
98 test_expect_success 'diff attribute' '
99 git reset --hard &&
100 echo third >file &&
101
102 git config diff.parrot.command echo &&
103
104 echo >.gitattributes "file diff=parrot" &&
105
106 git diff | {
107 read path oldfile oldhex oldmode newfile newhex newmode &&
108 test "z$path" = zfile &&
109 test "z$oldmode" = z100644 &&
110 test "z$newhex" = "z$ZERO_OID" &&
111 test "z$newmode" = z100644 &&
112 oh=$(git rev-parse --verify HEAD:file) &&
113 test "z$oh" = "z$oldhex"
114 }
115
116 '
117
118 test_expect_success 'diff attribute should apply only to diff' '
119
120 git log -p -1 HEAD |
121 grep "^diff --git a/file b/file"
122
123 '
124
125 test_expect_success 'diff attribute and --no-ext-diff' '
126
127 git diff --no-ext-diff |
128 grep "^diff --git a/file b/file"
129
130 '
131
132 test_expect_success 'diff attribute' '
133
134 git config --unset diff.parrot.command &&
135 git config diff.color.command echo &&
136
137 echo >.gitattributes "file diff=color" &&
138
139 git diff | {
140 read path oldfile oldhex oldmode newfile newhex newmode &&
141 test "z$path" = zfile &&
142 test "z$oldmode" = z100644 &&
143 test "z$newhex" = "z$ZERO_OID" &&
144 test "z$newmode" = z100644 &&
145 oh=$(git rev-parse --verify HEAD:file) &&
146 test "z$oh" = "z$oldhex"
147 }
148
149 '
150
151 test_expect_success 'diff attribute should apply only to diff' '
152
153 git log -p -1 HEAD |
154 grep "^diff --git a/file b/file"
155
156 '
157
158 test_expect_success 'diff attribute and --no-ext-diff' '
159
160 git diff --no-ext-diff |
161 grep "^diff --git a/file b/file"
162
163 '
164
165 test_expect_success 'GIT_EXTERNAL_DIFF trumps diff.external' '
166 >.gitattributes &&
167 test_config diff.external "echo ext-global" &&
168 GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env
169 '
170
171 test_expect_success 'attributes trump GIT_EXTERNAL_DIFF and diff.external' '
172 test_config diff.foo.command "echo ext-attribute" &&
173 test_config diff.external "echo ext-global" &&
174 echo "file diff=foo" >.gitattributes &&
175 GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-attribute
176 '
177
178 test_expect_success 'no diff with -diff' '
179 echo >.gitattributes "file -diff" &&
180 git diff | grep Binary
181 '
182
183 echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
184
185 test_expect_success 'force diff with "diff"' '
186 after=$(git hash-object file) &&
187 after=$(git rev-parse --short $after) &&
188 echo >.gitattributes "file diff" &&
189 git diff >actual &&
190 sed -e "s/^index .*/index $before..$after 100644/" \
191 "$TEST_DIRECTORY"/t4020/diff.NUL >expected-diff &&
192 test_cmp expected-diff actual
193 '
194
195 test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
196 echo anotherfile > file2 &&
197 git add file2 &&
198 git commit -m "added 2nd file" &&
199 echo modified >file2 &&
200 GIT_EXTERNAL_DIFF=echo git diff
201 '
202
203 test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
204 write_script external-diff.sh <<-\EOF &&
205 echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt
206 EOF
207 >counter.txt &&
208 cat >expect <<-\EOF &&
209 1 of 2
210 2 of 2
211 EOF
212 GIT_EXTERNAL_DIFF=./external-diff.sh git diff &&
213 test_cmp expect counter.txt
214 '
215
216 test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
217 touch file.ext &&
218 git add file.ext &&
219 echo with extension > file.ext &&
220 GIT_EXTERNAL_DIFF=echo git diff file.ext | grep ......_file\.ext &&
221 git update-index --force-remove file.ext &&
222 rm file.ext
223 '
224
225 echo "#!$SHELL_PATH" >fake-diff.sh
226 cat >> fake-diff.sh <<\EOF
227 cat $2 >> crlfed.txt
228 EOF
229 chmod a+x fake-diff.sh
230
231 keep_only_cr () {
232 tr -dc '\015'
233 }
234
235 test_expect_success 'external diff with autocrlf = true' '
236 test_config core.autocrlf true &&
237 GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
238 test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
239 '
240
241 test_expect_success 'diff --cached' '
242 test_config core.autocrlf true &&
243 git add file &&
244 git update-index --assume-unchanged file &&
245 echo second >file &&
246 git diff --cached >actual &&
247 test_cmp expected-diff actual
248 '
249
250 test_expect_success 'clean up crlf leftovers' '
251 git update-index --no-assume-unchanged file &&
252 rm -f file* &&
253 git reset --hard
254 '
255
256 test_expect_success 'submodule diff' '
257 git init sub &&
258 ( cd sub && test_commit sub1 ) &&
259 git add sub &&
260 test_tick &&
261 git commit -m "add submodule" &&
262 ( cd sub && test_commit sub2 ) &&
263 write_script gather_pre_post.sh <<-\EOF &&
264 echo "$1 $4" # path, mode
265 cat "$2" # old file
266 cat "$5" # new file
267 EOF
268 GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&
269 cat >expected <<-EOF &&
270 sub 160000
271 Subproject commit $(git rev-parse HEAD:sub)
272 Subproject commit $(cd sub && git rev-parse HEAD)
273 EOF
274 test_cmp expected actual
275 '
276
277 test_done