3 test_description
='external diff interface test'
5 TEST_PASSES_SANITIZE_LEAK
=true
8 test_expect_success setup
'
13 git commit -m initial &&
17 before=$(git hash-object file) &&
18 before=$(git rev-parse --short $before) &&
20 git commit -m second &&
26 test_expect_success
'GIT_EXTERNAL_DIFF environment' '
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"
40 test_expect_success
'GIT_EXTERNAL_DIFF environment should apply only to diff' '
42 GIT_EXTERNAL_DIFF=echo git log -p -1 HEAD |
43 grep "^diff --git a/file b/file"
47 test_expect_success
'GIT_EXTERNAL_DIFF environment and --no-ext-diff' '
49 GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff |
50 grep "^diff --git a/file b/file"
54 test_expect_success SYMLINKS
'typechange diff' '
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"
66 GIT_EXTERNAL_DIFF=echo git diff --no-ext-diff >actual &&
68 test_cmp expect actual
71 test_expect_success
'diff.external' '
74 test_config diff.external echo &&
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"
86 test_expect_success
'diff.external should apply only to diff' '
87 test_config diff.external echo &&
89 grep "^diff --git a/file b/file"
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"
98 test_expect_success
'diff attribute' '
102 git config diff.parrot.command echo &&
104 echo >.gitattributes "file diff=parrot" &&
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"
118 test_expect_success
'diff attribute should apply only to diff' '
121 grep "^diff --git a/file b/file"
125 test_expect_success
'diff attribute and --no-ext-diff' '
127 git diff --no-ext-diff |
128 grep "^diff --git a/file b/file"
132 test_expect_success
'diff attribute' '
134 git config --unset diff.parrot.command &&
135 git config diff.color.command echo &&
137 echo >.gitattributes "file diff=color" &&
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"
151 test_expect_success
'diff attribute should apply only to diff' '
154 grep "^diff --git a/file b/file"
158 test_expect_success
'diff attribute and --no-ext-diff' '
160 git diff --no-ext-diff |
161 grep "^diff --git a/file b/file"
165 test_expect_success
'GIT_EXTERNAL_DIFF trumps diff.external' '
167 test_config diff.external "echo ext-global" &&
168 GIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env
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
178 test_expect_success
'no diff with -diff' '
179 echo >.gitattributes "file -diff" &&
180 git diff | grep Binary
183 echo NULZbetweenZwords | perl
-pe 'y/Z/\000/' > file
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" &&
190 sed -e "s/^index .*/index $before..$after 100644/" \
191 "$TEST_DIRECTORY"/t4020/diff.NUL >expected-diff &&
192 test_cmp expected-diff actual
195 test_expect_success
'GIT_EXTERNAL_DIFF with more than one changed files' '
196 echo anotherfile > file2 &&
198 git commit -m "added 2nd file" &&
199 echo modified >file2 &&
200 GIT_EXTERNAL_DIFF=echo git diff
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
208 cat >expect <<-\EOF &&
212 GIT_EXTERNAL_DIFF=./external-diff.sh git diff &&
213 test_cmp expect counter.txt
216 test_expect_success
'GIT_EXTERNAL_DIFF generates pretty paths' '
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 &&
225 echo "#!$SHELL_PATH" >fake-diff.sh
226 cat >> fake-diff.sh
<<\EOF
229 chmod a
+x fake-diff.sh
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)
241 test_expect_success
'diff --cached' '
242 test_config core.autocrlf true &&
244 git update-index --assume-unchanged file &&
246 git diff --cached >actual &&
247 test_cmp expected-diff actual
250 test_expect_success
'clean up crlf leftovers' '
251 git update-index --no-assume-unchanged file &&
256 test_expect_success
'submodule diff' '
258 ( cd sub && test_commit sub1 ) &&
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
268 GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&
269 cat >expected <<-EOF &&
271 Subproject commit $(git rev-parse HEAD:sub)
272 Subproject commit $(cd sub && git rev-parse HEAD)
274 test_cmp expected actual