@matheusbsbs / matheus-bagliano / commits / 3e97c7c6af
Fork 0

No diff -b/-w output for all-whitespace changes

Change git-diff's whitespace-ignoring modes to generate output only if a non-empty patch results, which git-apply rejects. Update the tests to look for the new behavior. Signed-off-by: Greg Bacon <gbacon@dbresearch.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Greg Bacon committed Nov 19, 2009 at 15:12 UTC 3e97c7c6af2901cec63bf35fcd43ae3472e24af8
2 files changed +39 -10
diff.c
+27 -8
@@ -189,6 +189,7 @@ struct emit_callback {
189 struct diff_words_data *diff_words;
190 int *found_changesp;
191 FILE *file;
192 + struct strbuf *header;
193 };
194
195 static int count_lines(const char *data, int size)
@@ -755,6 +756,11 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
756 const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
757 const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
758
759 + if (ecbdata->header) {
760 + fprintf(ecbdata->file, "%s", ecbdata->header->buf);
761 + strbuf_reset(ecbdata->header);
762 + ecbdata->header = NULL;
763 + }
764 *(ecbdata->found_changesp) = 1;
765
766 if (ecbdata->label_path[0]) {
@@ -1561,6 +1567,7 @@ static void builtin_diff(const char *name_a,
1567 const char *reset = diff_get_color_opt(o, DIFF_RESET);
1568 const char *a_prefix, *b_prefix;
1569 const char *textconv_one = NULL, *textconv_two = NULL;
1570 + struct strbuf header = STRBUF_INIT;
1571
1572 if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
1573 (!one->mode || S_ISGITLINK(one->mode)) &&
@@ -1595,25 +1602,26 @@ static void builtin_diff(const char *name_a,
1602 b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
1603 lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
1604 lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
1598 - fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
1605 + strbuf_addf(&header, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
1606 if (lbl[0][0] == '/') {
1607 /* /dev/null */
1601 - fprintf(o->file, "%snew file mode %06o%s\n", set, two->mode, reset);
1608 + strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset);
1609 if (xfrm_msg && xfrm_msg[0])
1603 - fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
1610 + strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1611 }
1612 else if (lbl[1][0] == '/') {
1606 - fprintf(o->file, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
1613 + strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
1614 if (xfrm_msg && xfrm_msg[0])
1608 - fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
1615 + strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1616 }
1617 else {
1618 if (one->mode != two->mode) {
1612 - fprintf(o->file, "%sold mode %06o%s\n", set, one->mode, reset);
1613 - fprintf(o->file, "%snew mode %06o%s\n", set, two->mode, reset);
1619 + strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset);
1620 + strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset);
1621 }
1622 if (xfrm_msg && xfrm_msg[0])
1616 - fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
1623 + strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1624 +
1625 /*
1626 * we do not run diff between different kind
1627 * of objects.
@@ -1623,6 +1631,8 @@ static void builtin_diff(const char *name_a,
1631 if (complete_rewrite &&
1632 (textconv_one || !diff_filespec_is_binary(one)) &&
1633 (textconv_two || !diff_filespec_is_binary(two))) {
1634 + fprintf(o->file, "%s", header.buf);
1635 + strbuf_reset(&header);
1636 emit_rewrite_diff(name_a, name_b, one, two,
1637 textconv_one, textconv_two, o);
1638 o->found_changes = 1;
@@ -1640,6 +1650,8 @@ static void builtin_diff(const char *name_a,
1650 if (mf1.size == mf2.size &&
1651 !memcmp(mf1.ptr, mf2.ptr, mf1.size))
1652 goto free_ab_and_return;
1653 + fprintf(o->file, "%s", header.buf);
1654 + strbuf_reset(&header);
1655 if (DIFF_OPT_TST(o, BINARY))
1656 emit_binary_diff(o->file, &mf1, &mf2);
1657 else
@@ -1656,6 +1668,11 @@ static void builtin_diff(const char *name_a,
1668 struct emit_callback ecbdata;
1669 const struct userdiff_funcname *pe;
1670
1671 + if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS)) {
1672 + fprintf(o->file, "%s", header.buf);
1673 + strbuf_reset(&header);
1674 + }
1675 +
1676 if (textconv_one) {
1677 size_t size;
1678 mf1.ptr = run_textconv(textconv_one, one, &size);
@@ -1685,6 +1702,7 @@ static void builtin_diff(const char *name_a,
1702 if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
1703 check_blank_at_eof(&mf1, &mf2, &ecbdata);
1704 ecbdata.file = o->file;
1705 + ecbdata.header = header.len ? &header : NULL;
1706 xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
1707 xecfg.ctxlen = o->context;
1708 xecfg.interhunkctxlen = o->interhunkcontext;
@@ -1729,6 +1747,7 @@ static void builtin_diff(const char *name_a,
1747 }
1748
1749 free_ab_and_return:
1750 + strbuf_release(&header);
1751 diff_free_filespec_data(one);
1752 diff_free_filespec_data(two);
1753 free(a_one);
t/t4015-diff-whitespace.sh
+12 -2
@@ -93,8 +93,6 @@ git diff > out
93 test_expect_success 'another test, without options' 'test_cmp expect out'
94
95 cat << EOF > expect
96 -diff --git a/x b/x
97 -index d99af23..8b32fb5 100644
96 EOF
97 git diff -w > out
98 test_expect_success 'another test, with -w' 'test_cmp expect out'
@@ -386,6 +384,18 @@ test_expect_success 'checkdiff allows new blank lines' '
384 git diff --check
385 '
386
387 +cat <<EOF >expect
388 +EOF
389 +test_expect_success 'whitespace-only changes not reported' '
390 + git reset --hard &&
391 + echo >x "hello world" &&
392 + git add x &&
393 + git commit -m "hello 1" &&
394 + echo >x "hello world" &&
395 + git diff -b >actual &&
396 + test_cmp expect actual
397 +'
398 +
399 test_expect_success 'combined diff with autocrlf conversion' '
400
401 git reset --hard &&