merge-ort: fix massive leak

When a series of merges was performed (such as for a rebase or series of cherry-picks), only the data structures allocated by the final merge operation were being freed. The problem was that while picking out pieces of merge-ort to upstream, I previously misread a certain section of merge_start() and assumed it was associated with a later optimization. Include that section now, which ensures that if there was a previous merge operation, that we clear out result->priv and then re-use it for opt->priv, and otherwise we allocate opt->priv. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Jan 23, 2021 at 22:01 UTC cf8937acdedc80e636587f5fc2f495ea38bd5fe0
1 file changed +17
merge-ort.c
+17
@@ -3227,11 +3227,28 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
3227 assert(opt->obuf.len == 0);
3228
3229 assert(opt->priv == NULL);
3230 + if (result->priv) {
3231 + opt->priv = result->priv;
3232 + result->priv = NULL;
3233 + /*
3234 + * opt->priv non-NULL means we had results from a previous
3235 + * run; do a few sanity checks that user didn't mess with
3236 + * it in an obvious fashion.
3237 + */
3238 + assert(opt->priv->call_depth == 0);
3239 + assert(!opt->priv->toplevel_dir ||
3240 + 0 == strlen(opt->priv->toplevel_dir));
3241 + }
3242
3243 /* Default to histogram diff. Actually, just hardcode it...for now. */
3244 opt->xdl_opts = DIFF_WITH_ALG(opt, HISTOGRAM_DIFF);
3245
3246 /* Initialization of opt->priv, our internal merge data */
3247 + if (opt->priv) {
3248 + clear_or_reinit_internal_opts(opt->priv, 1);
3249 + trace2_region_leave("merge", "allocate/init", opt->repo);
3250 + return;
3251 + }
3252 opt->priv = xcalloc(1, sizeof(*opt->priv));
3253
3254 /* Initialization of various renames fields */