From: "blanet via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Elijah Newren <newren@gmail.com>, blanet <bupt_xingxin@163.com>,
Xing Xin <xingxin.xx@bytedance.com>
Subject: [PATCH v2] diff-tree: fix crash when used with --remerge-diff
Date: Fri, 09 Aug 2024 07:24:52 +0000 [thread overview]
Message-ID: <pull.1771.v2.git.1723188292498.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1771.git.1723123250958.gitgitgadget@gmail.com>
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).
Elijah Newren, the author of the remerge diff feature, notes that other
callers of `log-tree.c:log_tree_commit` (the only caller of
`log-tree.c:do_remerge_diff`) also exist, but:
`builtin/am.c`: manually sets all flags; remerge_diff is not among them
`sequencer.c`: manually sets all flags; remerge_diff is not among them
so `builtin/diff-tree.c` really is the only caller that was overlooked
when remerge-diff functionality was added.
This commit resolves the crash by adding `remerge_objdir` setup logic to
`builtin/diff-tree.c`, mirroring `builtin/log.c:cmd_log_walk_no_free`.
It also includes the necessary cleanup for `remerge_objdir`.
Reviewed-by: Elijah Newren <newren@gmail.com>
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-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1771/blanet/xx/fix-diff-tree-crash-on-remerge-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1771
Range-diff vs v1:
1: f0b86faa275 ! 1: 57f0b1247d8 diff-tree: fix crash when used with --remerge-diff
@@ Commit message
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?!?
+ $ 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
@@ Commit message
"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.
+ Elijah Newren, the author of the remerge diff feature, notes that other
+ callers of `log-tree.c:log_tree_commit` (the only caller of
+ `log-tree.c:do_remerge_diff`) also exist, but:
+ `builtin/am.c`: manually sets all flags; remerge_diff is not among them
+ `sequencer.c`: manually sets all flags; remerge_diff is not among them
+
+ so `builtin/diff-tree.c` really is the only caller that was overlooked
+ when remerge-diff functionality was added.
+
+ This commit resolves the crash by adding `remerge_objdir` setup logic to
+ `builtin/diff-tree.c`, mirroring `builtin/log.c:cmd_log_walk_no_free`.
+ It also includes the necessary cleanup for `remerge_objdir`.
+
+ Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Xing Xin <xingxin.xx@bytedance.com>
## builtin/diff-tree.c ##
@@
+ #include "read-cache-ll.h"
#include "repository.h"
#include "revision.h"
- #include "tree.h"
+#include "tmp-objdir.h"
+ #include "tree.h"
static struct rev_info log_tree_opt;
-
@@ builtin/diff-tree.c: int cmd_diff_tree(int argc, const char **argv, const char *prefix)
opt->diffopt.rotate_to_strict = 1;
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..b8df1d4b79b 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -8,6 +8,7 @@
#include "read-cache-ll.h"
#include "repository.h"
#include "revision.h"
+#include "tmp-objdir.h"
#include "tree.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
next prev parent reply other threads:[~2024-08-09 7:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` blanet via GitGitGadget [this message]
2024-08-09 15:32 ` [PATCH v2] " Junio C Hamano
2024-08-09 15:46 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1771.v2.git.1723188292498.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=bupt_xingxin@163.com \
--cc=git@vger.kernel.org \
--cc=newren@gmail.com \
--cc=xingxin.xx@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).