git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] diff-tree: fix crash when used with --remerge-diff
@ 2024-08-08 13:20 blanet via GitGitGadget
  2024-08-08 16:03 ` Elijah Newren
  2024-08-09  7:24 ` [PATCH v2] " blanet via GitGitGadget
  0 siblings, 2 replies; 7+ messages in thread
From: blanet via GitGitGadget @ 2024-08-08 13:20 UTC (permalink / raw)
  To: git; +Cc: Elijah Newren, blanet, Xing Xin

From: Xing Xin <xingxin.xx@bytedance.com>

When using "git-diff-tree" to get the tree diff for merge commits with
the diff format set to `remerge`, a bug is triggered as shown below:

    $ git diff-tree -r --remerge-diff 363337e6eb
    363337e6eb812d0c0d785ed4261544f35559ff8b
    BUG: log-tree.c:1006: did a remerge diff without remerge_objdir?!?

This bug is reported by `log-tree.c:do_remerge_diff`, where a bug check
added in commit 7b90ab467a (log: clean unneeded objects during log
--remerge-diff, 2022-02-02) detects the absence of `remerge_objdir` when
attempting to clean up temporary objects generated during the remerge
process.

After some further digging, I find that the remerge-related diff options
were introduced in db757e8b8d (show, log: provide a --remerge-diff
capability, 2022-02-02), which also affect the setup of `rev_info` for
"git-diff-tree", but were not accounted for in the original
implementation (inferred from the commit message).

This commit fixes the bug by adding initialization logic for
`remerge_objdir` in `builtin/diff-tree.c`, mirroring the logic in
`builtin/log.c:cmd_log_walk_no_free`. A final cleanup for
`remerge_objdir` is also included.

Signed-off-by: Xing Xin <xingxin.xx@bytedance.com>
---
    diff-tree: fix crash when used with --remerge-diff

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1771%2Fblanet%2Fxx%2Ffix-diff-tree-crash-on-remerge-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1771/blanet/xx/fix-diff-tree-crash-on-remerge-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1771

 builtin/diff-tree.c     | 13 +++++++++++++
 t/t4069-remerge-diff.sh | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 0d3c611aac0..813be486dad 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -9,6 +9,7 @@
 #include "repository.h"
 #include "revision.h"
 #include "tree.h"
+#include "tmp-objdir.h"
 
 static struct rev_info log_tree_opt;
 
@@ -166,6 +167,13 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 
 	opt->diffopt.rotate_to_strict = 1;
 
+	if (opt->remerge_diff) {
+		opt->remerge_objdir = tmp_objdir_create("remerge-diff");
+		if (!opt->remerge_objdir)
+			die(_("unable to create temporary object directory"));
+		tmp_objdir_replace_primary_odb(opt->remerge_objdir, 1);
+	}
+
 	/*
 	 * NOTE!  We expect "a..b" to expand to "^a b" but it is
 	 * perfectly valid for revision range parser to yield "b ^a",
@@ -230,5 +238,10 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 		diff_free(&opt->diffopt);
 	}
 
+	if (opt->remerge_diff) {
+		tmp_objdir_destroy(opt->remerge_objdir);
+		opt->remerge_objdir = NULL;
+	}
+
 	return diff_result_code(&opt->diffopt);
 }
diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh
index 07323ebafe0..ca8f999caba 100755
--- a/t/t4069-remerge-diff.sh
+++ b/t/t4069-remerge-diff.sh
@@ -110,6 +110,41 @@ test_expect_success 'can filter out additional headers with pickaxe' '
 	test_must_be_empty actual
 '
 
+test_expect_success 'remerge-diff also works for git-diff-tree' '
+	# With a clean merge
+	git diff-tree -r -p --remerge-diff --no-commit-id bc_resolution >actual &&
+	test_must_be_empty actual &&
+
+	# With both a resolved conflict and an unrelated change
+	cat <<-EOF >tmp &&
+	diff --git a/numbers b/numbers
+	remerge CONFLICT (content): Merge conflict in numbers
+	index a1fb731..6875544 100644
+	--- a/numbers
+	+++ b/numbers
+	@@ -1,13 +1,9 @@
+	 1
+	 2
+	-<<<<<<< b0ed5cb (change_a)
+	-three
+	-=======
+	-tres
+	->>>>>>> 6cd3f82 (change_b)
+	+drei
+	 4
+	 5
+	 6
+	 7
+	-eight
+	+acht
+	 9
+	EOF
+	sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >expect &&
+	git diff-tree -r -p --remerge-diff --no-commit-id ab_resolution >tmp &&
+	sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'setup non-content conflicts' '
 	git switch --orphan base &&
 

base-commit: 406f326d271e0bacecdb00425422c5fa3f314930
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-08-09 15:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-08 13:20 [PATCH] diff-tree: fix crash when used with --remerge-diff blanet via GitGitGadget
2024-08-08 16:03 ` Elijah Newren
2024-08-08 17:24   ` Junio C Hamano
2024-08-09  7:25   ` Xing Xin
2024-08-09  7:24 ` [PATCH v2] " blanet via GitGitGadget
2024-08-09 15:32   ` Junio C Hamano
2024-08-09 15:46     ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).