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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.