diff --cached: do not borrow from a work tree when a path is marked as assume-unchanged
authorJunio C Hamano <gitster@pobox.com>
Sun, 22 Mar 2009 22:26:07 +0000 (15:26 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 22 Mar 2009 22:26:07 +0000 (15:26 -0700)
When the index says that the file in the work tree that corresponds to the
blob object that is used for comparison is known to be unchanged, "diff"
reads from the file and applies convert_to_git(), instead of inflating the
object, to feed the internal diff engine with, because an earlier
benchnark found that it tends to be faster to use this optimization.

However, the index can lie when the path is marked as assume-unchanged.
Disable the optimization for such paths.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff.c
t/t4020-diff-external.sh
diff --git a/diff.c b/diff.c
index bf5d5f15a3b54f1e1a0a2068990e899fd869d435..c2d277a52df271ef4488f81f4f9d42684893af92 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1687,7 +1687,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
        struct stat st;
        int pos, len;
 
-       /* We do not read the cache ourselves here, because the
+       /*
+        * We do not read the cache ourselves here, because the
         * benchmark with my previous version that always reads cache
         * shows that it makes things worse for diff-tree comparing
         * two linux-2.6 kernel trees in an already checked out work
@@ -1727,6 +1728,13 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
        if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
                return 0;
 
+       /*
+        * If ce is marked as "assume unchanged", there is no
+        * guarantee that work tree matches what we are looking for.
+        */
+       if (ce->ce_flags & CE_VALID)
+               return 0;
+
        /*
         * If ce matches the file in the work tree, we can reuse it.
         */
index 637b4e19d52e81cf1472a4ed9dcfb0c9ff00da2b..f853b8a894246f1f9d09c18656e290a2e2f9ce6d 100755 (executable)
@@ -107,4 +107,12 @@ test_expect_success 'force diff with "diff"' '
        test_cmp ../t4020/diff.NUL actual
 '
 
+test_expect_success 'diff --cached' '
+       git add file &&
+       git update-index --assume-unchanged file &&
+       echo second >file &&
+       git diff --cached >actual &&
+       test_cmp ../t4020/diff.NUL actual
+'
+
 test_done