]> git.ipfire.org Git - thirdparty/git.git/commitdiff
commit-graph: avoid malloc'ing a local variable
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Thu, 15 May 2025 13:11:41 +0000 (13:11 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 May 2025 20:46:45 +0000 (13:46 -0700)
We do need a context to write the commit graph, but that context is only
needed during the life time of `commit_graph_write()`, therefore it can
easily be a stack variable.

This also helps CodeQL recognize that it is safe to assign the address
of other local variables to the context's fields.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit-graph.c

index 6394752b0b0868b4337cf36f5747c2a9b36c364c..9f0115dac9b528405ddd35fe5f1664f247e8b832 100644 (file)
@@ -2509,7 +2509,17 @@ int write_commit_graph(struct object_directory *odb,
                       const struct commit_graph_opts *opts)
 {
        struct repository *r = the_repository;
-       struct write_commit_graph_context *ctx;
+       struct write_commit_graph_context ctx = {
+               .r = r,
+               .odb = odb,
+               .append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0,
+               .report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0,
+               .split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0,
+               .opts = opts,
+               .total_bloom_filter_data_size = 0,
+               .write_generation_data = (get_configured_generation_version(r) == 2),
+               .num_generation_data_overflows = 0,
+       };
        uint32_t i;
        int res = 0;
        int replace = 0;
@@ -2531,17 +2541,6 @@ int write_commit_graph(struct object_directory *odb,
                return 0;
        }
 
-       CALLOC_ARRAY(ctx, 1);
-       ctx->r = r;
-       ctx->odb = odb;
-       ctx->append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0;
-       ctx->report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0;
-       ctx->split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0;
-       ctx->opts = opts;
-       ctx->total_bloom_filter_data_size = 0;
-       ctx->write_generation_data = (get_configured_generation_version(r) == 2);
-       ctx->num_generation_data_overflows = 0;
-
        bloom_settings.hash_version = r->settings.commit_graph_changed_paths_version;
        bloom_settings.bits_per_entry = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY",
                                                      bloom_settings.bits_per_entry);
@@ -2549,14 +2548,14 @@ int write_commit_graph(struct object_directory *odb,
                                                  bloom_settings.num_hashes);
        bloom_settings.max_changed_paths = git_env_ulong("GIT_TEST_BLOOM_SETTINGS_MAX_CHANGED_PATHS",
                                                         bloom_settings.max_changed_paths);
-       ctx->bloom_settings = &bloom_settings;
+       ctx.bloom_settings = &bloom_settings;
 
        init_topo_level_slab(&topo_levels);
-       ctx->topo_levels = &topo_levels;
+       ctx.topo_levels = &topo_levels;
 
-       prepare_commit_graph(ctx->r);
-       if (ctx->r->objects->commit_graph) {
-               struct commit_graph *g = ctx->r->objects->commit_graph;
+       prepare_commit_graph(ctx.r);
+       if (ctx.r->objects->commit_graph) {
+               struct commit_graph *g = ctx.r->objects->commit_graph;
 
                while (g) {
                        g->topo_levels = &topo_levels;
@@ -2565,15 +2564,15 @@ int write_commit_graph(struct object_directory *odb,
        }
 
        if (flags & COMMIT_GRAPH_WRITE_BLOOM_FILTERS)
-               ctx->changed_paths = 1;
+               ctx.changed_paths = 1;
        if (!(flags & COMMIT_GRAPH_NO_WRITE_BLOOM_FILTERS)) {
                struct commit_graph *g;
 
-               g = ctx->r->objects->commit_graph;
+               g = ctx.r->objects->commit_graph;
 
                /* We have changed-paths already. Keep them in the next graph */
                if (g && g->bloom_filter_settings) {
-                       ctx->changed_paths = 1;
+                       ctx.changed_paths = 1;
 
                        /* don't propagate the hash_version unless unspecified */
                        if (bloom_settings.hash_version == -1)
@@ -2586,116 +2585,114 @@ int write_commit_graph(struct object_directory *odb,
 
        bloom_settings.hash_version = bloom_settings.hash_version == 2 ? 2 : 1;
 
-       if (ctx->split) {
-               struct commit_graph *g = ctx->r->objects->commit_graph;
+       if (ctx.split) {
+               struct commit_graph *g = ctx.r->objects->commit_graph;
 
                while (g) {
-                       ctx->num_commit_graphs_before++;
+                       ctx.num_commit_graphs_before++;
                        g = g->base_graph;
                }
 
-               if (ctx->num_commit_graphs_before) {
-                       ALLOC_ARRAY(ctx->commit_graph_filenames_before, ctx->num_commit_graphs_before);
-                       i = ctx->num_commit_graphs_before;
-                       g = ctx->r->objects->commit_graph;
+               if (ctx.num_commit_graphs_before) {
+                       ALLOC_ARRAY(ctx.commit_graph_filenames_before, ctx.num_commit_graphs_before);
+                       i = ctx.num_commit_graphs_before;
+                       g = ctx.r->objects->commit_graph;
 
                        while (g) {
-                               ctx->commit_graph_filenames_before[--i] = xstrdup(g->filename);
+                               ctx.commit_graph_filenames_before[--i] = xstrdup(g->filename);
                                g = g->base_graph;
                        }
                }
 
-               if (ctx->opts)
-                       replace = ctx->opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
+               if (ctx.opts)
+                       replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
        }
 
-       ctx->approx_nr_objects = repo_approximate_object_count(the_repository);
+       ctx.approx_nr_objects = repo_approximate_object_count(the_repository);
 
-       if (ctx->append && ctx->r->objects->commit_graph) {
-               struct commit_graph *g = ctx->r->objects->commit_graph;
+       if (ctx.append && ctx.r->objects->commit_graph) {
+               struct commit_graph *g = ctx.r->objects->commit_graph;
                for (i = 0; i < g->num_commits; i++) {
                        struct object_id oid;
                        oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i),
                                the_repository->hash_algo);
-                       oid_array_append(&ctx->oids, &oid);
+                       oid_array_append(&ctx.oids, &oid);
                }
        }
 
        if (pack_indexes) {
-               ctx->order_by_pack = 1;
-               if ((res = fill_oids_from_packs(ctx, pack_indexes)))
+               ctx.order_by_pack = 1;
+               if ((res = fill_oids_from_packs(&ctx, pack_indexes)))
                        goto cleanup;
        }
 
        if (commits) {
-               if ((res = fill_oids_from_commits(ctx, commits)))
+               if ((res = fill_oids_from_commits(&ctx, commits)))
                        goto cleanup;
        }
 
        if (!pack_indexes && !commits) {
-               ctx->order_by_pack = 1;
-               fill_oids_from_all_packs(ctx);
+               ctx.order_by_pack = 1;
+               fill_oids_from_all_packs(&ctx);
        }
 
-       close_reachable(ctx);
+       close_reachable(&ctx);
 
-       copy_oids_to_commits(ctx);
+       copy_oids_to_commits(&ctx);
 
-       if (ctx->commits.nr >= GRAPH_EDGE_LAST_MASK) {
+       if (ctx.commits.nr >= GRAPH_EDGE_LAST_MASK) {
                error(_("too many commits to write graph"));
                res = -1;
                goto cleanup;
        }
 
-       if (!ctx->commits.nr && !replace)
+       if (!ctx.commits.nr && !replace)
                goto cleanup;
 
-       if (ctx->split) {
-               split_graph_merge_strategy(ctx);
+       if (ctx.split) {
+               split_graph_merge_strategy(&ctx);
 
                if (!replace)
-                       merge_commit_graphs(ctx);
+                       merge_commit_graphs(&ctx);
        } else
-               ctx->num_commit_graphs_after = 1;
+               ctx.num_commit_graphs_after = 1;
 
-       ctx->trust_generation_numbers = validate_mixed_generation_chain(ctx->r->objects->commit_graph);
+       ctx.trust_generation_numbers = validate_mixed_generation_chain(ctx.r->objects->commit_graph);
 
-       compute_topological_levels(ctx);
-       if (ctx->write_generation_data)
-               compute_generation_numbers(ctx);
+       compute_topological_levels(&ctx);
+       if (ctx.write_generation_data)
+               compute_generation_numbers(&ctx);
 
-       if (ctx->changed_paths)
-               compute_bloom_filters(ctx);
+       if (ctx.changed_paths)
+               compute_bloom_filters(&ctx);
 
-       res = write_commit_graph_file(ctx);
+       res = write_commit_graph_file(&ctx);
 
-       if (ctx->changed_paths)
+       if (ctx.changed_paths)
                deinit_bloom_filters();
 
-       if (ctx->split)
-               mark_commit_graphs(ctx);
+       if (ctx.split)
+               mark_commit_graphs(&ctx);
 
-       expire_commit_graphs(ctx);
+       expire_commit_graphs(&ctx);
 
 cleanup:
-       free(ctx->graph_name);
-       free(ctx->base_graph_name);
-       free(ctx->commits.list);
-       oid_array_clear(&ctx->oids);
+       free(ctx.graph_name);
+       free(ctx.base_graph_name);
+       free(ctx.commits.list);
+       oid_array_clear(&ctx.oids);
        clear_topo_level_slab(&topo_levels);
 
-       for (i = 0; i < ctx->num_commit_graphs_before; i++)
-               free(ctx->commit_graph_filenames_before[i]);
-       free(ctx->commit_graph_filenames_before);
+       for (i = 0; i < ctx.num_commit_graphs_before; i++)
+               free(ctx.commit_graph_filenames_before[i]);
+       free(ctx.commit_graph_filenames_before);
 
-       for (i = 0; i < ctx->num_commit_graphs_after; i++) {
-               free(ctx->commit_graph_filenames_after[i]);
-               free(ctx->commit_graph_hash_after[i]);
+       for (i = 0; i < ctx.num_commit_graphs_after; i++) {
+               free(ctx.commit_graph_filenames_after[i]);
+               free(ctx.commit_graph_hash_after[i]);
        }
-       free(ctx->commit_graph_filenames_after);
-       free(ctx->commit_graph_hash_after);
-
-       free(ctx);
+       free(ctx.commit_graph_filenames_after);
+       free(ctx.commit_graph_hash_after);
 
        return res;
 }