diff options
| author | Xing Xin <xingxin.xx@bytedance.com> | 2024-08-09 07:24:52 +0000 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-08-09 08:07:44 -0700 |
| commit | a77554ea0972e4ec3518fb8fb0b2582c76cf3105 (patch) | |
| tree | d871a1c96680bb8d82b57dc18db1908dbc471196 /builtin/diff-tree.c | |
| parent | 337b4d400023d22207bcc3c29e9ebab31bf96fc2 (diff) | |
diff-tree: fix crash when used with --remerge-diff
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/diff-tree.c')
| -rw-r--r-- | builtin/diff-tree.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index a8e68ce8ef..12012ea093 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -9,6 +9,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; @@ -167,6 +168,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", @@ -231,5 +239,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); } |
