summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Rast <tr@thomasrast.ch>2014-02-16 17:52:34 +0100
committerJunio C Hamano <gitster@pobox.com>2014-02-18 12:06:08 -0800
commitaba4727281612c3e24914691727e11e1f44a9aac (patch)
tree046c974c9f70052cd9b29a7e18b2310eede101f6
parent2f93541d88fadd1ff5307d81c2c8921ee3eea058 (diff)
downloadgit-tr/diff-submodule-no-reuse-worktree.tar.gz
diff: do not reuse_worktree_file for submodulestr/diff-submodule-no-reuse-worktree
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>
-rw-r--r--diff.c5
-rwxr-xr-xt/t4020-diff-external.sh30
2 files changed, 32 insertions, 3 deletions
diff --git a/diff.c b/diff.c
index 266112ca61..a96992a1bd 100644
--- a/diff.c
+++ b/diff.c
@@ -2842,8 +2842,9 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
remove_tempfile_installed = 1;
}
- if (!one->sha1_valid ||
- reuse_worktree_file(name, one->sha1, 1)) {
+ if (!S_ISGITLINK(one->mode) &&
+ (!one->sha1_valid ||
+ reuse_worktree_file(name, one->sha1, 1))) {
struct stat st;
if (lstat(name, &st) < 0) {
if (errno == ENOENT)
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 2e7d73f090..295a563496 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -213,12 +213,13 @@ keep_only_cr () {
}
test_expect_success 'external diff with autocrlf = true' '
- git config core.autocrlf true &&
+ test_config core.autocrlf true &&
GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
'
test_expect_success 'diff --cached' '
+ test_config core.autocrlf true &&
git add file &&
git update-index --assume-unchanged file &&
echo second >file &&
@@ -226,4 +227,31 @@ test_expect_success 'diff --cached' '
test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
'
+test_expect_success 'clean up crlf leftovers' '
+ git update-index --no-assume-unchanged file &&
+ rm -f file* &&
+ git reset --hard
+'
+
+test_expect_success 'submodule diff' '
+ git init sub &&
+ ( cd sub && test_commit sub1 ) &&
+ git add sub &&
+ test_tick &&
+ git commit -m "add submodule" &&
+ ( cd sub && test_commit sub2 ) &&
+ write_script gather_pre_post.sh <<-\EOF &&
+ echo "$1 $4" # path, mode
+ cat "$2" # old file
+ cat "$5" # new file
+ EOF
+ GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&
+ cat >expected <<-EOF &&
+ sub 160000
+ Subproject commit $(git rev-parse HEAD:sub)
+ Subproject commit $(cd sub && git rev-parse HEAD)
+ EOF
+ test_cmp expected actual
+'
+
test_done