Must not modify the_index.cache as it may be passed to realloc at some point.
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index a7e76719d12a9083c465d60eee333aa880b5a1c2..71b340c5368fb287ce7d7b242aa51436ed5dda93 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -17,8 +17,9 @@
 #endif
 
 static int diff_detect_rename_default;
-static int diff_rename_limit_default = -1;
+static int diff_rename_limit_default = 100;
 static int diff_use_color_default;
+int diff_auto_refresh_index = 1;
 
 static char diff_colors[][COLOR_MAXLEN] = {
        "\033[m",       /* reset */
@@ -166,6 +167,10 @@ int git_diff_ui_config(const char *var, const char *value)
                        diff_detect_rename_default = DIFF_DETECT_RENAME;
                return 0;
        }
+       if (!strcmp(var, "diff.autorefreshindex")) {
+               diff_auto_refresh_index = git_config_bool(var, value);
+               return 0;
+       }
        if (!prefixcmp(var, "diff.")) {
                const char *ep = strrchr(var, '.');
 
@@ -1670,7 +1675,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
        return 0;
 }
 
-void diff_free_filespec_data(struct diff_filespec *s)
+void diff_free_filespec_blob(struct diff_filespec *s)
 {
        if (s->should_free)
                free(s->data);
@@ -1681,6 +1686,11 @@ void diff_free_filespec_data(struct diff_filespec *s)
                s->should_free = s->should_munmap = 0;
                s->data = NULL;
        }
+}
+
+void diff_free_filespec_data(struct diff_filespec *s)
+{
+       diff_free_filespec_blob(s);
        free(s->cnt_data);
        s->cnt_data = NULL;
 }
@@ -3139,6 +3149,22 @@ static void diffcore_apply_filter(const char *filter)
        *q = outq;
 }
 
+/* Check whether two filespecs with the same mode and size are identical */
+static int diff_filespec_is_identical(struct diff_filespec *one,
+                                     struct diff_filespec *two)
+{
+       if (S_ISGITLINK(one->mode)) {
+               diff_fill_sha1_info(one);
+               diff_fill_sha1_info(two);
+               return !hashcmp(one->sha1, two->sha1);
+       }
+       if (diff_populate_filespec(one, 0))
+               return 0;
+       if (diff_populate_filespec(two, 0))
+               return 0;
+       return !memcmp(one->data, two->data, one->size);
+}
+
 static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
 {
        int i;
@@ -3170,10 +3196,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
                    diff_populate_filespec(p->one, 1) ||
                    diff_populate_filespec(p->two, 1) ||
                    (p->one->size != p->two->size) ||
-
-                   diff_populate_filespec(p->one, 0) || /* (2) */
-                   diff_populate_filespec(p->two, 0) ||
-                   memcmp(p->one->data, p->two->data, p->one->size))
+                   !diff_filespec_is_identical(p->one, p->two)) /* (2) */
                        diff_q(&outq, p);
                else {
                        /*