diff: shortcut for diff'ing two binary SHA-1 objects

If we are given two SHA-1 and asked to determine if they are different (but not _what_ differences), we know right away by comparing SHA-1. A side effect of this patch is, because large files are marked binary, diff-tree will not need to unpack them. 'diff-index --cached' will not either. But 'diff-files' still does. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Aug 16, 2014 at 10:08 UTC 1aaf69e669b7fd67073d3024b386ac25ac77d0f8
2 files changed +23
diff.c
+13
@@ -2324,6 +2324,19 @@ static void builtin_diff(const char *name_a,
2324 } else if (!DIFF_OPT_TST(o, TEXT) &&
2325 ( (!textconv_one && diff_filespec_is_binary(one)) ||
2326 (!textconv_two && diff_filespec_is_binary(two)) )) {
2327 + if (!one->data && !two->data &&
2328 + S_ISREG(one->mode) && S_ISREG(two->mode) &&
2329 + !DIFF_OPT_TST(o, BINARY)) {
2330 + if (!hashcmp(one->sha1, two->sha1)) {
2331 + if (must_show_header)
2332 + fprintf(o->file, "%s", header.buf);
2333 + goto free_ab_and_return;
2334 + }
2335 + fprintf(o->file, "%s", header.buf);
2336 + fprintf(o->file, "%sBinary files %s and %s differ\n",
2337 + line_prefix, lbl[0], lbl[1]);
2338 + goto free_ab_and_return;
2339 + }
2340 if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
2341 die("unable to read files to diff");
2342 /* Quite common confusing case */
t/t1050-large.sh
+10
@@ -116,6 +116,16 @@ test_expect_success 'diff --stat' '
116 git diff --stat HEAD^ HEAD
117 '
118
119 +test_expect_success 'diff' '
120 + git diff HEAD^ HEAD >actual &&
121 + grep "Binary files.*differ" actual
122 +'
123 +
124 +test_expect_success 'diff --cached' '
125 + git diff --cached HEAD^ >actual &&
126 + grep "Binary files.*differ" actual
127 +'
128 +
129 test_expect_success 'hash-object' '
130 git hash-object large1
131 '