aboutsummaryrefslogtreecommitdiffstats
path: root/merge-ort.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2024-06-11 11:21:11 +0200
committerJunio C Hamano <gitster@pobox.com>2024-06-11 13:15:08 -0700
commit44ec7c575f914d77787a17cefd094e3c46b8b12b (patch)
tree185a726b608127146430586f18dcdbb77f981372 /merge-ort.c
parentbuiltin/merge: fix leaking `struct cmdnames` in `get_strategy()` (diff)
downloadgit-44ec7c575f914d77787a17cefd094e3c46b8b12b.tar.gz
git-44ec7c575f914d77787a17cefd094e3c46b8b12b.zip
merge: fix leaking merge bases
When calling either the recursive or the ORT merge machineries we need to provide a list of merge bases. The ownership of that parameter is then implicitly transferred to the callee, which is somewhat fishy. Furthermore, that list may leak in some cases where the merge machinery runs into an error, thus causing a memory leak. Refactor the code such that we stop transferring ownership. Instead, the merge machinery will now create its own local copies of the passed in list as required if they need to modify the list. Free the list at the callsites as required. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'merge-ort.c')
-rw-r--r--merge-ort.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/merge-ort.c b/merge-ort.c
index eaede6cead..8ed8a4c9dc 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -5071,11 +5071,12 @@ redo:
* Originally from merge_recursive_internal(); somewhat adapted, though.
*/
static void merge_ort_internal(struct merge_options *opt,
- struct commit_list *merge_bases,
+ const struct commit_list *_merge_bases,
struct commit *h1,
struct commit *h2,
struct merge_result *result)
{
+ struct commit_list *merge_bases = copy_commit_list(_merge_bases);
struct commit *next;
struct commit *merged_merge_bases;
const char *ancestor_name;
@@ -5085,7 +5086,7 @@ static void merge_ort_internal(struct merge_options *opt,
if (repo_get_merge_bases(the_repository, h1, h2,
&merge_bases) < 0) {
result->clean = -1;
- return;
+ goto out;
}
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
merge_bases = reverse_commit_list(merge_bases);
@@ -5129,7 +5130,7 @@ static void merge_ort_internal(struct merge_options *opt,
opt->branch2 = "Temporary merge branch 2";
merge_ort_internal(opt, NULL, prev, next, result);
if (result->clean < 0)
- return;
+ goto out;
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
@@ -5152,6 +5153,9 @@ static void merge_ort_internal(struct merge_options *opt,
result);
strbuf_release(&merge_base_abbrev);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
+
+out:
+ free_commit_list(merge_bases);
}
void merge_incore_nonrecursive(struct merge_options *opt,
@@ -5181,7 +5185,7 @@ void merge_incore_nonrecursive(struct merge_options *opt,
}
void merge_incore_recursive(struct merge_options *opt,
- struct commit_list *merge_bases,
+ const struct commit_list *merge_bases,
struct commit *side1,
struct commit *side2,
struct merge_result *result)