Subject: [PATCH] diff: stop output garbled message in dry run mode

From: "Lidong Yan via GitGitGadget" <[email-masked]>
Date: Fri, 17 Oct 2025 03:17:29 +0000

From: Lidong Yan <[email-masked]>

In dry run mode, diff_flush_patch() should not produce any output.
However, in commit b55e6d36eb (diff: ensure consistent diff behavior
with ignore options, 2025-08-08), only the output during the
comparison of two file contents was suppressed. For file deletions
or mode changes, diff_flush_patch() still produces output. In
run_extern_diff(), set quiet to true if in dry run mode. In
emit_diff_symbol_from_struct(), directly return if in dry run mode.

Signed-off-by: Lidong Yan <[email-masked]>
---
    diff: stop output garbled message in dry run mode
    
    In dry run mode, diff_flush_patch() should not produce any output.
    However, in commit b55e6d36eb (diff: ensure consistent diff behavior
    with ignore options, 2025-08-08), only the output during the comparison
    of two file contents was suppressed. For file deletions or mode changes,
    diff_flush_patch() still produces output. In run_extern_diff(), set
    quiet to true if in dry run mode. In emit_diff_symbol_from_struct(),
    directly return if in dry run mode.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2071%2Fbrandb97%2Ffix-diff-dry-run-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2071/brandb97/fix-diff-dry-run-v1
Pull-Request: https://github.com/git/git/pull/2071

 diff.c                  |  5 ++++-
 t/t4013-diff-various.sh | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/diff.c b/diff.c
index 87fa16b730..4baf9b535e 100644
--- a/diff.c
+++ b/diff.c
@@ -1351,6 +1351,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
 	int len = eds->len;
 	unsigned flags = eds->flags;
 
+	if (o->dry_run)
+		return;
+
 	switch (s) {
 	case DIFF_SYMBOL_NO_LF_EOF:
 		context = diff_get_color_opt(o, DIFF_CONTEXT);
@@ -4420,7 +4423,7 @@ static void run_external_diff(const struct external_diff *pgm,
 {
 	struct child_process cmd = CHILD_PROCESS_INIT;
 	struct diff_queue_struct *q = &diff_queued_diff;
-	int quiet = !(o->output_format & DIFF_FORMAT_PATCH);
+	int quiet = !(o->output_format & DIFF_FORMAT_PATCH) || o->dry_run;
 	int rc;
 
 	/*
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 55a06eadb3..25fa452656 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -661,6 +661,27 @@ test_expect_success 'diff -I<regex>: ignore matching file' '
 	test_grep ! "file1" actual
 '
 
+test_expect_success 'diff -I<regex>: ignore all content changes' '
+	test_when_finished "git rm -f file1 file2" &&
+	: >file1 &&
+	git add file1 &&
+	: >file2 &&
+	git add file2 &&
+
+	rm -f file1 file2 &&
+	mkdir file2 &&
+	test_diff_no_content_changes () {
+		git diff $1 --ignore-blank-lines -I".*" >actual &&
+		test_line_count = 2 actual &&
+		test_grep "file1" actual &&
+		test_grep "file2" actual &&
+		test_grep ! "diff --git" actual
+	} &&
+	test_diff_no_content_changes "--raw" &&
+	test_diff_no_content_changes "--name-only" &&
+	test_diff_no_content_changes "--name-status"
+'
+
 # check_prefix <patch> <src> <dst>
 # check only lines with paths to avoid dependency on exact oid/contents
 check_prefix () {

base-commit: 143f58ef7535f8f8a80d810768a18bdf3807de26
-- 
gitgitgadget