diff --git a/diff.c b/diff.c index 12a4122fe7..648f6717a5 100644 --- a/diff.c +++ b/diff.c @@ -3399,6 +3399,21 @@ 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) +{ + /* + * This function specifically looks for pairs injected by + * create_filepairs_for_header_only_notifications(). Such + * pairs are "phoney" in that they do not represent any + * content or even mode difference, but were inserted because + * diff_queued_diff previously had no pair associated with + * that path but we needed some pair to avoid losing the + * "remerge CONFLICT" header associated with the path. + */ + 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, @@ -3430,14 +3445,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); @@ -3457,12 +3474,12 @@ 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 + * We should only reach this point for pairs generated from * create_filepairs_for_header_only_notifications(). For - * these, we should avoid the "/dev/null" special casing - * above, meaning we avoid showing such pairs as either + * these, we want to avoid the "/dev/null" special casing + * above, because we do not want such pairs shown as either * "new file" or "deleted file" below. */ lbl[0] = a_one; @@ -5853,6 +5870,7 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o) { int include_conflict_headers = (additional_headers(o, p->one->path) && + !o->pickaxe_opts && (!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o))); /* @@ -5908,6 +5926,8 @@ int diff_queue_is_empty(struct diff_options *o) int i; int include_conflict_headers = (o->additional_path_headers && + strmap_get_size(o->additional_path_headers) && + !o->pickaxe_opts && (!o->filter || filter_bit_tst(DIFF_STATUS_UNMERGED, o))); if (include_conflict_headers) diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh index 9e7cac68b1..07323ebafe 100755 --- a/t/t4069-remerge-diff.sh +++ b/t/t4069-remerge-diff.sh @@ -2,7 +2,6 @@ test_description='remerge-diff handling' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test is ort-specific @@ -57,6 +56,11 @@ test_expect_success 'remerge-diff on a clean merge' ' test_cmp expect actual ' +test_expect_success 'remerge-diff on a clean merge with a filter' ' + git show --oneline --remerge-diff --diff-filter=U bc_resolution >actual && + test_must_be_empty actual +' + test_expect_success 'remerge-diff with both a resolved conflict and an unrelated change' ' git log -1 --oneline ab_resolution >tmp && cat <<-EOF >>tmp && @@ -90,6 +94,22 @@ test_expect_success 'remerge-diff with both a resolved conflict and an unrelated test_cmp expect actual ' +test_expect_success 'pickaxe still includes additional headers for relevant changes' ' + # reuses "expect" from the previous testcase + + git log --oneline --remerge-diff -Sacht ab_resolution >tmp && + sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual && + test_cmp expect actual +' + +test_expect_success 'can filter out additional headers with pickaxe' ' + git show --remerge-diff --submodule=log --find-object=HEAD ab_resolution >actual && + test_must_be_empty actual && + + git show --remerge-diff -S"not present" --all >actual && + test_must_be_empty actual +' + test_expect_success 'setup non-content conflicts' ' git switch --orphan base && @@ -185,6 +205,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 &&