diff mbox series

[v2,1/3] diff: have submodule_format logic avoid additional diff headers

Message ID aea0bbc1c6a33d62f6b3313d56664d53df8f620a.1662016087.git.gitgitgadget@gmail.com (mailing list archive)
State New, archived
Headers show
Series Output fixes for --remerge-diff | expand

Commit Message

Elijah Newren Sept. 1, 2022, 7:08 a.m. UTC
From: Elijah Newren <newren@gmail.com>

Commit 95433eeed9 ("diff: add ability to insert additional headers for
paths", 2022-02-02) introduced the possibility of additional headers,
created in create_filepairs_for_header_only_notifications().  These are
represented by inserting additional pairs in diff_queued_diff which
always have a mode of 0 and a null_oid.  When these were added, one
code path was noted to assume that at least one of the diff_filespecs
in the pair were valid, and that codepath was corrected.

The submodule_format handling is another codepath with the same issue;
it would operate on these additional headers and attempt to display them
as submodule changes.  Prevent that by explicitly checking for both
modes being 0.

Reported-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
 diff.c                  | 14 +++++++++++---
 t/t4069-remerge-diff.sh |  8 ++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

Comments

Junio C Hamano Sept. 1, 2022, 4:30 p.m. UTC | #1
"Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com> writes:


As there is no guarantee that we'd never add another hack to use a
different kind of "phoney" filepair to diff_queue for another
purpose, either the name of the helper function, or a comment in
front of it, should say something that is sufficient to help readers
understand ...

> +static int diff_filepair_is_phoney(struct diff_filespec *one,
> +				   struct diff_filespec *two)
> +{
> +	return !DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two);
> +}
> ...
> -	if (!DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two)) {
> +	if (diff_filepair_is_phoney(one, two)) {
>  		/*
>  		 * We should only reach this point for pairs from
>  		 * create_filepairs_for_header_only_notifications().  For

... some of what this comment said, i.e. the pair that was added by
create_filepairs_for_header_only_notifications() is what the helper
detects. 

Other than that, the whole series looks good.
diff mbox series

Patch

diff --git a/diff.c b/diff.c
index 974626a6211..d672efed7ab 100644
--- a/diff.c
+++ b/diff.c
@@ -3398,6 +3398,12 @@  static void add_formatted_headers(struct strbuf *msg,
 				     line_prefix, meta, reset);
 }
 
+static int diff_filepair_is_phoney(struct diff_filespec *one,
+				   struct diff_filespec *two)
+{
+	return !DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two);
+}
+
 static void builtin_diff(const char *name_a,
 			 const char *name_b,
 			 struct diff_filespec *one,
@@ -3429,14 +3435,16 @@  static void builtin_diff(const char *name_a,
 
 	if (o->submodule_format == DIFF_SUBMODULE_LOG &&
 	    (!one->mode || S_ISGITLINK(one->mode)) &&
-	    (!two->mode || S_ISGITLINK(two->mode))) {
+	    (!two->mode || S_ISGITLINK(two->mode)) &&
+	    (!diff_filepair_is_phoney(one, two))) {
 		show_submodule_diff_summary(o, one->path ? one->path : two->path,
 				&one->oid, &two->oid,
 				two->dirty_submodule);
 		return;
 	} else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
 		   (!one->mode || S_ISGITLINK(one->mode)) &&
-		   (!two->mode || S_ISGITLINK(two->mode))) {
+		   (!two->mode || S_ISGITLINK(two->mode)) &&
+		   (!diff_filepair_is_phoney(one, two))) {
 		show_submodule_inline_diff(o, one->path ? one->path : two->path,
 				&one->oid, &two->oid,
 				two->dirty_submodule);
@@ -3456,7 +3464,7 @@  static void builtin_diff(const char *name_a,
 	b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
 	lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
 	lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
-	if (!DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two)) {
+	if (diff_filepair_is_phoney(one, two)) {
 		/*
 		 * We should only reach this point for pairs from
 		 * create_filepairs_for_header_only_notifications().  For
diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh
index 9e7cac68b1c..e3e6fbd97b2 100755
--- a/t/t4069-remerge-diff.sh
+++ b/t/t4069-remerge-diff.sh
@@ -185,6 +185,14 @@  test_expect_success 'remerge-diff w/ diff-filter=U: all conflict headers, no dif
 	test_cmp expect actual
 '
 
+test_expect_success 'submodule formatting ignores additional headers' '
+	# Reuses "expect" from last testcase
+
+	git show --oneline --remerge-diff --diff-filter=U --submodule=log >tmp &&
+	sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'remerge-diff w/ diff-filter=R: relevant file + conflict header' '
 	git log -1 --oneline resolution >tmp &&
 	cat <<-EOF >>tmp &&