diff: do not reuse_worktree_file for submodules
The GIT_EXTERNAL_DIFF calling code attempts to reuse existing worktree files for the worktree side of diffs, for performance reasons. However, that code also tries to do the same with submodules. This results in calls to $GIT_EXTERNAL_DIFF where the old-file is a file of the form "Submodule commit $sha1", but the new-file is a directory in the worktree. Fix it by never reusing a worktree "file" in the submodule case. Reported-by: Grégory Pakosz <gregory.pakosz@gmail.com> Signed-off-by: Thomas Rast <tr@thomasrast.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Thomas Rast committed
Feb 16, 2014 at 17:52 UTC
aba4727281612c3e24914691727e11e1f44a9aac
2 files changed
+32
-3
diff.c
+3
-2
@@ -2842,8 +2842,9 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
2842
remove_tempfile_installed = 1;
2843
}
2844
2845
- if (!one->sha1_valid ||
2846
- reuse_worktree_file(name, one->sha1, 1)) {
2845
+ if (!S_ISGITLINK(one->mode) &&
2846
+ (!one->sha1_valid ||
2847
+ reuse_worktree_file(name, one->sha1, 1))) {
2848
struct stat st;
2849
if (lstat(name, &st) < 0) {
2850
if (errno == ENOENT)
t/t4020-diff-external.sh
+29
-1
@@ -213,12 +213,13 @@ keep_only_cr () {
213
}
214
215
test_expect_success 'external diff with autocrlf = true' '
216
- git config core.autocrlf true &&
216
+ test_config core.autocrlf true &&
217
GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
218
test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
219
'
220
221
test_expect_success 'diff --cached' '
222
+ test_config core.autocrlf true &&
223
git add file &&
224
git update-index --assume-unchanged file &&
225
echo second >file &&
@@ -226,4 +227,31 @@ test_expect_success 'diff --cached' '
227
test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
228
'
229
230
+test_expect_success 'clean up crlf leftovers' '
231
+ git update-index --no-assume-unchanged file &&
232
+ rm -f file* &&
233
+ git reset --hard
234
+'
235
+
236
+test_expect_success 'submodule diff' '
237
+ git init sub &&
238
+ ( cd sub && test_commit sub1 ) &&
239
+ git add sub &&
240
+ test_tick &&
241
+ git commit -m "add submodule" &&
242
+ ( cd sub && test_commit sub2 ) &&
243
+ write_script gather_pre_post.sh <<-\EOF &&
244
+ echo "$1 $4" # path, mode
245
+ cat "$2" # old file
246
+ cat "$5" # new file
247
+ EOF
248
+ GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&
249
+ cat >expected <<-EOF &&
250
+ sub 160000
251
+ Subproject commit $(git rev-parse HEAD:sub)
252
+ Subproject commit $(cd sub && git rev-parse HEAD)
253
+ EOF
254
+ test_cmp expected actual
255
+'
256
+
257
test_done