From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Calvin Wan <calvinwan@google.com>
Cc: git@vger.kernel.org, chooglen@google.com, gitster@pobox.com,
newren@gmail.com, levraiphilippeblain@gmail.com,
Johannes.Schindelin@gmx.de
Subject: Re: [PATCH v5] submodule merge: update conflict error message
Date: Mon, 25 Jul 2022 14:11:34 +0200 [thread overview]
Message-ID: <220725.86r129pd8m.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <220725.868rohragt.gmgdl@evledraar.gmail.com>
On Mon, Jul 25 2022, Ævar Arnfjörð Bjarmason wrote:
> On Mon, Jul 18 2022, Calvin Wan wrote:
>
>
> One of the CI failures in "seen" is because of my topic to mark (among
> other things) t1500*.sh as passing with SANITIZE=leak, and this change.
>
> Because...
>
>> ..
>> object_array_clear(&merges);
>> cleanup:
>> + if (!ret) {
>> + if (!csub) {
>> + CALLOC_ARRAY(csub, 1);
>> + }
>> + csub_item.oid = xstrdup(repo_find_unique_abbrev(&subrepo, b, DEFAULT_ABBREV));
>> + csub_item.path = xstrdup(path);
>> + csub_item.resolution_exists = resolution_exists;
>> + ALLOC_GROW(csub->items, csub->nr + 1, csub->alloc);
>
> ... in "cleanup" we're ALLOC_GROW()-ing? I haven't looked into this yet,
> but this seems susppect. This is line 1879 in the following stacktrace:
>
> + git -C super merge branch1
> Failed to merge submodule dir/sub
> CONFLICT (submodule): Merge conflict in dir/sub
> Recursive merging with submodules currently only supports trivial cases.
> Please manually handle the merging of each conflicted submodule.
> This can be accomplished with the following steps:
> - go to submodule (dir/sub), and either merge commit 7018b5f
> or update to an existing commit which has merged those changes
> - come back to superproject, and `git add dir/sub` to record the above merge or update
> - resolve any other conflicts in the superproject
> - commit the resulting index in the superproject
> Automatic merge failed; fix conflicts and then commit the result.
>
> =================================================================
> ==31261==ERROR: LeakSanitizer: detected memory leaks
>
> Direct leak of 576 byte(s) in 1 object(s) allocated from:
> #0 0x4565ad in __interceptor_realloc (git+0x4565ad)
> #1 0x76ecfd in xrealloc wrapper.c:136:8
> #2 0x64fcd3 in merge_submodule merge-ort.c:1879:3
> #3 0x64ee9b in handle_content_merge merge-ort.c:2118:11
> #4 0x651c14 in process_entry merge-ort.c:4056:17
> #5 0x648c05 in process_entries merge-ort.c:4267:4
> #6 0x646c03 in merge_ort_nonrecursive_internal merge-ort.c:4893:2
> #7 0x6470f3 in merge_ort_internal merge-ort.c:4982:2
> #8 0x646de0 in merge_incore_recursive merge-ort.c:5033:2
> #9 0x652d1a in merge_ort_recursive merge-ort-wrappers.c:57:2
> #10 0x4ec0f6 in try_merge_strategy builtin/merge.c:764:12
> #11 0x4e9bf2 in cmd_merge builtin/merge.c:1710:9
> #12 0x45a3aa in run_builtin git.c:466:11
> #13 0x458e41 in handle_builtin git.c:720:3
> #14 0x459d85 in run_argv git.c:787:4
> #15 0x458bfa in cmd_main git.c:920:19
> #16 0x56a049 in main common-main.c:56:11
> #17 0x7fe592bca81c in __libc_start_main csu/../csu/libc-start.c:332:16
> #18 0x431139 in _start (git+0x431139)
Looking at this a bit more this fixes it, and also the NIH allocation
pattern & what we can do with a "struct string_list" instead of managing
our own allocations.
I did wonder why you need to allocate the "oid" at all, i.e. at the time
of merge_submodules() can't we just squirrel away the "const struct
object_id *" and only when we emit the message later run
repo_find_unique_abbrev()?
I think we can do that, but it means re-init-ing the submodule, and I'm
not sure if there's any edge cases with the state changing between us
trying merge_submodules() and the eventual messages we emit.
But it would mean that we'd just need to allocate a pointer to that oid
+ resolution_exists.
Perhaps we could also continue down that path and do this with just one
allocation for that "oid/resolution_exists" side-data. I.e. you'd have a
second string_list in the struct, have a non-NULL util mean "resolution
exists", and the "string" there would be nodup'd (we could refer to the
"string" in the first one).
But I think all of that probably isn't worth it, but the below seems
like a good trade-off & good place to stop, and fixes the memory leak
this topic introduces.
merge-ort.c | 69 +++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 40 insertions(+), 29 deletions(-)
diff --git a/merge-ort.c b/merge-ort.c
index 154d33f2f45..5cf87f70b58 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -293,16 +293,17 @@ struct rename_info {
};
struct conflicted_submodule_item {
- char *oid;
- char *path;
- int resolution_exists;
+ char *abbrev;
+ int resolution_exists:1;
};
-struct conflicted_submodule_list {
- struct conflicted_submodule_item *items;
- size_t nr;
- size_t alloc;
-};
+static void conflicted_submodule_item_free(void *util, const char *str)
+{
+ struct conflicted_submodule_item *item = util;
+
+ free(item->abbrev);
+ free(item);
+}
struct merge_options_internal {
/*
@@ -401,7 +402,7 @@ struct merge_options_internal {
int call_depth;
/* field that holds submodule conflict information */
- struct conflicted_submodule_list conflicted_submodules;
+ struct string_list conflicted_submodules;
};
struct version_info {
@@ -701,6 +702,9 @@ static void clear_or_reinit_internal_opts(struct merge_options_internal *opti,
mem_pool_discard(&opti->pool, 0);
+ string_list_clear_func(&opti->conflicted_submodules,
+ conflicted_submodule_item_free);
+
/* Clean out callback_data as well. */
FREE_AND_NULL(renames->callback_data);
renames->callback_data_nr = renames->callback_data_alloc = 0;
@@ -1756,8 +1760,6 @@ static int merge_submodule(struct merge_options *opt,
struct commit *commit_o, *commit_a, *commit_b;
int parent_count;
struct object_array merges;
- struct conflicted_submodule_list *csub = &opt->priv->conflicted_submodules;
- struct conflicted_submodule_item csub_item;
int resolution_exists = 0;
int i;
@@ -1870,15 +1872,17 @@ static int merge_submodule(struct merge_options *opt,
object_array_clear(&merges);
cleanup:
if (!ret) {
- if (!csub) {
- CALLOC_ARRAY(csub, 1);
- }
- csub_item.oid = xstrdup(repo_find_unique_abbrev(&subrepo, b, DEFAULT_ABBREV));
- csub_item.path = xstrdup(path);
- csub_item.resolution_exists = resolution_exists;
- ALLOC_GROW(csub->items, csub->nr + 1, csub->alloc);
- csub->items[csub->nr++] = csub_item;
- opt->priv->conflicted_submodules = *csub;
+ struct string_list *csub = &opt->priv->conflicted_submodules;
+ struct conflicted_submodule_item *util;
+ const char *abbrev;
+
+ abbrev = repo_find_unique_abbrev(&subrepo, b, DEFAULT_ABBREV);;
+
+ util = xmalloc(sizeof(*util));
+ util->abbrev = xstrdup(abbrev);
+ util->resolution_exists = resolution_exists;
+
+ string_list_append(csub, path)->util = util;
}
repo_clear(&subrepo);
return ret;
@@ -4465,23 +4469,26 @@ static int record_conflicted_index_entries(struct merge_options *opt)
return errs;
}
-static void print_submodule_conflict_suggestion(struct conflicted_submodule_list *csub) {
- if (csub && csub->nr > 0) {
- int i;
+static void print_submodule_conflict_suggestion(struct string_list *csub) {
+ if (csub->nr > 0) {
+ struct string_list_item *item;
+
printf(_("Recursive merging with submodules currently only supports trivial cases.\n"
"Please manually handle the merging of each conflicted submodule.\n"
"This can be accomplished with the following steps:\n"));
- for (i = 0; i < csub->nr; i++) {
+
+ for_each_string_list_item(item, csub) {
+ struct conflicted_submodule_item *util = item->util;
+
printf(_(" - go to submodule (%s), and either merge commit %s\n"
"or update to an existing commit which has merged those changes\n"),
- csub->items[i].path,
- csub->items[i].oid);
- if (csub->items[i].resolution_exists)
+ item->string, util->abbrev);
+ if (util->resolution_exists)
printf(_("such as one listed above\n"));
}
printf(_(" - come back to superproject, and `git add"));
- for (i = 0; i < csub->nr; i++)
- printf(_(" %s"), csub->items[i].path);
+ for_each_string_list_item(item, csub)
+ printf(_(" %s"), item->string);
printf(_("` to record the above merge or update \n"
" - resolve any other conflicts in the superproject\n"
" - commit the resulting index in the superproject\n"));
@@ -4538,6 +4545,8 @@ void merge_display_update_messages(struct merge_options *opt,
string_list_clear(&olist, 0);
print_submodule_conflict_suggestion(&opti->conflicted_submodules);
+ string_list_clear_func(&opti->conflicted_submodules,
+ conflicted_submodule_item_free);
/* Also include needed rename limit adjustment now */
diff_warn_rename_limit("merge.renamelimit",
@@ -4795,6 +4804,8 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
*/
strmap_init(&opt->priv->conflicts);
+ string_list_init_dup(&opt->priv->conflicted_submodules);
+
trace2_region_leave("merge", "allocate/init", opt->repo);
}
next prev parent reply other threads:[~2022-07-25 12:53 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-06 23:54 [PATCH] submodule merge: update conflict error message Calvin Wan
2022-06-07 0:48 ` Junio C Hamano
2022-06-08 17:19 ` Calvin Wan
2022-06-08 17:34 ` Glen Choo
2022-06-08 18:01 ` Calvin Wan
2022-06-08 19:13 ` Junio C Hamano
2022-06-10 23:11 ` [PATCH v2] " Calvin Wan
2022-06-11 4:53 ` Elijah Newren
2022-06-11 17:08 ` Philippe Blain
2022-06-12 6:56 ` Elijah Newren
2022-06-13 2:03 ` Calvin Wan
2022-06-12 23:30 ` Junio C Hamano
2022-06-13 1:54 ` Calvin Wan
2022-06-29 22:40 ` [PATCH v3] " Calvin Wan
2022-06-30 2:40 ` Elijah Newren
2022-06-30 19:48 ` Calvin Wan
2022-07-01 4:27 ` Elijah Newren
2022-06-30 20:35 ` Glen Choo
2022-06-30 20:45 ` Glen Choo
2022-06-30 21:08 ` Calvin Wan
2022-07-12 23:19 ` [PATCH v4] " Calvin Wan
2022-07-13 18:11 ` Junio C Hamano
2022-07-17 2:46 ` Elijah Newren
2022-07-15 12:57 ` Johannes Schindelin
2022-07-16 6:22 ` Junio C Hamano
2022-07-17 2:44 ` Elijah Newren
2022-07-18 17:03 ` Calvin Wan
2022-07-18 21:43 ` [PATCH v5] " Calvin Wan
2022-07-19 6:39 ` Junio C Hamano
2022-07-19 19:30 ` Calvin Wan
2022-07-19 20:16 ` Junio C Hamano
2022-07-19 7:13 ` Junio C Hamano
2022-07-19 19:07 ` Calvin Wan
2022-07-19 20:30 ` Junio C Hamano
2022-07-25 6:05 ` Ævar Arnfjörð Bjarmason
2022-07-25 12:11 ` Ævar Arnfjörð Bjarmason [this message]
2022-07-25 22:03 ` Calvin Wan
2022-07-25 12:31 ` Ævar Arnfjörð Bjarmason
2022-07-25 21:27 ` Calvin Wan
2022-07-26 21:00 ` [PATCH v6] " Calvin Wan
2022-07-27 1:13 ` Elijah Newren
2022-07-27 22:00 ` Calvin Wan
2022-07-28 0:41 ` Elijah Newren
2022-07-28 19:06 ` Calvin Wan
2022-07-27 9:20 ` Ævar Arnfjörð Bjarmason
2022-07-28 21:12 ` [PATCH v7] " Calvin Wan
2022-07-28 23:22 ` Ævar Arnfjörð Bjarmason
2022-07-29 0:24 ` Elijah Newren
2022-08-01 22:24 ` Calvin Wan
2022-08-01 12:06 ` Ævar Arnfjörð Bjarmason
2022-08-02 0:50 ` Junio C Hamano
2022-08-02 21:03 ` Calvin Wan
2022-08-02 21:11 ` Junio C Hamano
2022-08-02 21:55 ` Calvin Wan
2022-08-02 22:22 ` Junio C Hamano
2022-08-04 19:51 ` [PATCH v8] " Calvin Wan
2022-08-16 15:58 ` Junio C Hamano
2022-08-16 18:58 ` Junio C Hamano
2022-08-16 19:34 ` Calvin Wan
2022-08-16 19:39 ` 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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=220725.86r129pd8m.gmgdl@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=calvinwan@google.com \
--cc=chooglen@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=levraiphilippeblain@gmail.com \
--cc=newren@gmail.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).