git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re:Re: [PATCH] diff-tree: fix crash when used with --remerge-diff

From
XXXing Xin <bupt_xingxin@163.com>
Date
Aug 9, 2024, 07:25 UTC
Message-ID
<4bc36fb9.5f47.19136073c64.Coremail.bupt_xingxin@163.com>
In-Reply-To
<CABPp-BGo7-P+3w=Y2Mifox4xztzMhgLKBtnrrF9R1XM9ZDPqqw@mail.gmail.com>
At 2024-08-09 00:03:53, "Elijah Newren" <newren@gmail.com> wrote:
Show 18 quoted lines
>On Thu, Aug 8, 2024 at 6:20 AM blanet via GitGitGadget
><gitgitgadget@gmail.com> wrote:
>>
>> 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?!?
>
>Wow, this bug is around for 2.5 years, and then we both independently
>notice and fix it within 3 weeks of each other:
>https://github.com/git/git/commit/e5890667c7598e813edee0ac4e76d6e3cdd525ec
>
>My patch is incomplete as it's missing a testcase, and you submitted
>first, so let's stick with your fix, though.
Wow, such an interesting coincidence! And thanks for your quick reply!
Show 21 quoted lines
>> 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.
>
>The commit message from my patch also included an explanation for why
>diff-tree was the only caller that was missing the necessary logic
>(see the last paragraph, which kind of references the one before it as
>well).

Your explanations better illustrate the impact of this bug, I've quoted them in the new patch commit message.

[snip]
Show 25 quoted lines
>> 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"
>
>The includes other than this one are in alphabetical order; can you
>move this a line before?
>
>Also, as an aside, folks in this project often just put includes at
>the end, but I think it's a bad practice.  Whenever someone needs to
>backport fixes or merge separate patch topics into seen/next/etc. or
>even merge not-yet-upstream topics with newer upstream versions, this
>practice increases the odds of unnecessary conflicts.  And it makes it
>harder for the next person who comes along to spot whether a header is
>already included (and sometimes leaves us including headers twice).
>While each case is a small amount of toil so we tend to overlook it,
>it's totally unnecessary toil in many cases.  Putting includes in
>alphabetical order (other than the one include required to be first,
>git-compat-util.h or its documented stand-ins) can often remove this
>unnecessary toil.  Anyway, thanks for letting me vent.  :-)

Noted. I'll move the new include to the correct position. Thanks for the guidance!

Show 29 quoted lines
>>  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);
>>  }
>
>Your fix exactly matches mine, other than the header include location.
High five! :-)
[snip]
Xing Xin
Previous: Junio C HamanoNext: blanet via GitGitGadget
Message 4 of 7 in “diff-tree: fix crash when used with --remerge-diff”
  1. diff-tree: fix crash when used with --remerge-diffblanet via GitGitGadget, Aug 8, 2024
  2. Elijah NewrenAug 8, 2024
  3. Junio C HamanoAug 8, 2024
  4. Xing XinAug 9, 2024
  5. diff-tree: fix crash when used with --remerge-diffblanet via GitGitGadget, Aug 9, 2024
  6. Junio C HamanoAug 9, 2024
  7. Junio C HamanoAug 9, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.