Merge branch 'zj/diff-empty-chmod'
authorJunio C Hamano <gitster@pobox.com>
Mon, 7 May 2012 20:29:08 +0000 (13:29 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 May 2012 20:29:08 +0000 (13:29 -0700)
"git diff --stat" used to fully count a binary file with modified
execution bits whose contents is unmodified, which was not right.

By Zbigniew Jędrzejewski-Szmek (4) and Johannes Sixt (1)
* zj/diff-empty-chmod:
t4006: Windows do not have /dev/zero
diff --stat: do not run diff on indentical files
diff --stat: report mode-only changes for binary files like text files
tests: check --[short]stat output after chmod
test: modernize style of t4006

Conflicts:
diff.c

diff.c
t/t4006-diff-mode.sh
diff --git a/diff.c b/diff.c
index 02081d2af249d7fef660bd401a6d508b2e21cff1..77edd5086fff30af36e92a151377c285de21aca3 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1614,8 +1614,12 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
                if (data->files[i]->is_binary) {
                        fprintf(options->file, "%s", line_prefix);
                        show_name(options->file, prefix, name, len);
-                       fprintf(options->file, " %*s ", number_width, "Bin");
-                       fprintf(options->file, "%s%"PRIuMAX"%s",
+                       fprintf(options->file, " %*s", number_width, "Bin");
+                       if (!added && !deleted) {
+                               putc('\n', options->file);
+                               continue;
+                       }
+                       fprintf(options->file, " %s%"PRIuMAX"%s",
                                del_c, deleted, reset);
                        fprintf(options->file, " -> ");
                        fprintf(options->file, "%s%"PRIuMAX"%s",
@@ -1689,17 +1693,16 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option
                return;
 
        for (i = 0; i < data->nr; i++) {
-               if (!data->files[i]->is_binary &&
-                   !data->files[i]->is_unmerged) {
-                       int added = data->files[i]->added;
-                       int deleted= data->files[i]->deleted;
-                       if (!data->files[i]->is_renamed &&
-                           (added + deleted == 0)) {
-                               total_files--;
-                       } else {
-                               adds += added;
-                               dels += deleted;
-                       }
+               int added = data->files[i]->added;
+               int deleted= data->files[i]->deleted;
+
+               if (data->files[i]->is_unmerged)
+                       continue;
+               if (!data->files[i]->is_renamed && (added + deleted == 0)) {
+                       total_files--;
+               } else {
+                       adds += added;
+                       dels += deleted;
                }
        }
        if (options->output_prefix) {
@@ -2399,6 +2402,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
 {
        mmfile_t mf1, mf2;
        struct diffstat_file *data;
+       int same_contents;
 
        data = diffstat_add(diffstat, name_a, name_b);
 
@@ -2407,10 +2411,17 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
                return;
        }
 
+       same_contents = !hashcmp(one->sha1, two->sha1);
+
        if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
                data->is_binary = 1;
-               data->added = diff_filespec_size(two);
-               data->deleted = diff_filespec_size(one);
+               if (same_contents) {
+                       data->added = 0;
+                       data->deleted = 0;
+               } else {
+                       data->added = diff_filespec_size(two);
+                       data->deleted = diff_filespec_size(one);
+               }
        }
 
        else if (complete_rewrite) {
@@ -2420,7 +2431,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
                data->added = count_lines(two->data, two->size);
        }
 
-       else {
+       else if (!same_contents) {
                /* Crazy xdl interfaces.. */
                xpparam_t xpp;
                xdemitconf_t xecfg;
index ff8c2f7532aa6fd748dbbdc0322384576f3a35ed..7a3e1f9a24e4be3759c29acc632fc461ede2b74b 100755 (executable)
@@ -8,23 +8,52 @@ test_description='Test mode change diffs.
 '
 . ./test-lib.sh
 
-test_expect_success \
-    'setup' \
-    'echo frotz >rezrov &&
-     git update-index --add rezrov &&
-     tree=`git write-tree` &&
-     echo $tree'
-
-test_expect_success \
-    'chmod' \
-    'test_chmod +x rezrov &&
-     git diff-index $tree >current'
-
-sed -e 's/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /' <current >check
-echo ":100644 100755 X X M     rezrov" >expected
-
-test_expect_success \
-    'verify' \
-    'test_cmp expected check'
+sed_script='s/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /'
+
+test_expect_success 'setup' '
+       echo frotz >rezrov &&
+       git update-index --add rezrov &&
+       tree=`git write-tree` &&
+       echo $tree
+'
+
+test_expect_success 'chmod' '
+       test_chmod +x rezrov &&
+       git diff-index $tree >current &&
+       sed -e "$sed_script" <current >check &&
+       echo ":100644 100755 X X M      rezrov" >expected &&
+       test_cmp expected check
+'
+
+test_expect_success 'prepare binary file' '
+       git commit -m rezrov &&
+       printf "\00\01\02\03\04\05\06" >binbin &&
+       git add binbin &&
+       git commit -m binbin
+'
+
+test_expect_success '--stat output after text chmod' '
+       test_chmod -x rezrov &&
+       echo " 0 files changed" >expect &&
+       git diff HEAD --stat >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--shortstat output after text chmod' '
+       git diff HEAD --shortstat >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--stat output after binary chmod' '
+       test_chmod +x binbin &&
+       echo " 0 files changed" >expect &&
+       git diff HEAD --stat >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--shortstat output after binary chmod' '
+       git diff HEAD --shortstat >actual &&
+       test_cmp expect actual
+'
 
 test_done