diff --git a/Documentation/diff-options.adoc b/Documentation/diff-options.adoc index ae31520f7f1d130cefbe9f637715b4a96b9b2c66..6af1702bf507453b61b8adfc2d1a5be3f4981f74 100644 --- a/Documentation/diff-options.adoc +++ b/Documentation/diff-options.adoc @@ -544,6 +544,11 @@ ifndef::git-format-patch[] Implies `--patch`. endif::git-format-patch[] +`--report-binary-files`:: + In scenarios where Git detects a binary file and prints a "Binary files + differ" message, also report whether each file in the diff was + considered binary or text. + `--abbrev[=]`:: Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header diff --git a/diff.c b/diff.c index 87fa16b730dbeed0b68558ebe9497403824f3656..a8ca4550b933ace01bbf7377d1121efcf3d35af9 100644 --- a/diff.c +++ b/diff.c @@ -3534,6 +3534,15 @@ static int set_diff_algorithm(struct diff_options *opts, return 0; } +static void report_binary_file(struct strbuf *buf, + struct repository *repo, + struct diff_filespec *spec, + const char *path) +{ + const char *type = diff_filespec_is_binary(repo, spec) ? "binary" : "text"; + strbuf_addf(buf, "%s: %s\n", path, type); +} + static void builtin_diff(const char *name_a, const char *name_b, struct diff_filespec *one, @@ -3675,6 +3684,10 @@ static void builtin_diff(const char *name_a, header.buf, header.len, 0); strbuf_addf(&sb, "%sBinary files %s and %s differ\n", diff_line_prefix(o), lbl[0], lbl[1]); + if (o->report_binary_files) { + report_binary_file(&sb, o->repo, one, lbl[0]); + report_binary_file(&sb, o->repo, two, lbl[1]); + } emit_diff_symbol(o, DIFF_SYMBOL_BINARY_FILES, sb.buf, sb.len, 0); strbuf_release(&sb); @@ -3699,6 +3712,10 @@ static void builtin_diff(const char *name_a, else { strbuf_addf(&sb, "%sBinary files %s and %s differ\n", diff_line_prefix(o), lbl[0], lbl[1]); + if (o->report_binary_files) { + report_binary_file(&sb, o->repo, one, lbl[0]); + report_binary_file(&sb, o->repo, two, lbl[1]); + } emit_diff_symbol(o, DIFF_SYMBOL_BINARY_FILES, sb.buf, sb.len, 0); strbuf_release(&sb); @@ -5741,6 +5758,8 @@ struct option *add_diff_options(const struct option *opts, OPT_CALLBACK_F(0, "binary", options, NULL, N_("output a binary diff that can be applied"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, diff_opt_binary), + OPT_BOOL(0, "report-binary-files", &options->report_binary_files, + N_("report if pre- and post-image blobs are binary")), OPT_BOOL(0, "full-index", &options->flags.full_index, N_("show full pre- and post-image object names on the \"index\" lines")), OPT_COLOR_FLAG(0, "color", &options->use_color, diff --git a/diff.h b/diff.h index 2fa256c3ef00798b7d15c3b0af5d0d87e6a794d8..9024807ea9eaf8feb4e746ab9528f65469eb34a5 100644 --- a/diff.h +++ b/diff.h @@ -369,6 +369,13 @@ struct diff_options { */ int skip_resolving_statuses; + /* + * When generating patch diff output and a binary file is encountered, + * after printing the "Binary files differ" message, append a line for + * each file indicating whether Git considered it binary or text. + */ + int report_binary_files; + /* Callback which allows tweaking the options in diff_setup_done(). */ void (*set_default)(struct diff_options *); diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index d1d30ac2a9474eb6310f3249f20bd2cc56c562dc..8179371315855faabd4eb2494932e751040fc002 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -130,4 +130,31 @@ test_expect_success 'diff --stat with binary files and big change count' ' test_cmp expect actual ' +test_expect_success 'diff --report-binary-files' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + echo foo >foo && + git add foo && + git commit -m foo && + + printf "\0foo\0" >foo && + git commit -am binary && + + cat >expect <<-\EOF && + diff --git a/foo b/foo + index 257cc56..a60073c 100644 + Binary files a/foo and b/foo differ + a/foo: text + b/foo: binary + EOF + + git diff --report-binary-files HEAD~ HEAD >out && + + test_cmp expect out + ) +' + test_done