commit-graph: free all elements of graph chain

When running "commit-graph verify", we call free_commit_graph(). That's sufficient for the case of a single graph file, but if we loaded a chain of split graph files, they form a linked list via the base_graph pointers. We need to free all of them, or we leak all but the first struct. We can make this work by teaching free_commit_graph() to walk the base_graph pointers and free each element. This in turn lets us simplify close_commit_graph(), which does the same thing by recursion (we cannot just use close_commit_graph() in "commit-graph verify", as the function takes a pointer to an object store, and the verify command creates a single one-off graph struct). While indenting the code in free_commit_graph() for the loop, I noticed that setting g->data to NULL is rather pointless, as we free the struct a few lines later. So I cleaned that up while we're here. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Oct 3, 2023 at 16:29 UTC 09a75abba4eabab3f2cc4474e5d2db3a33a3a682
1 file changed +11 -18
commit-graph.c
+11 -18
@@ -723,19 +723,10 @@ struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r)
723 return NULL;
724 }
725
726 -static void close_commit_graph_one(struct commit_graph *g)
727 -{
728 - if (!g)
729 - return;
730 -
731 - close_commit_graph_one(g->base_graph);
732 - free_commit_graph(g);
733 -}
734 -
726 void close_commit_graph(struct raw_object_store *o)
727 {
728 clear_commit_graph_data_slab(&commit_graph_data_slab);
738 - close_commit_graph_one(o->commit_graph);
729 + free_commit_graph(o->commit_graph);
730 o->commit_graph = NULL;
731 }
732
@@ -2753,15 +2744,17 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
2744
2745 void free_commit_graph(struct commit_graph *g)
2746 {
2756 - if (!g)
2757 - return;
2758 - if (g->data) {
2759 - munmap((void *)g->data, g->data_len);
2760 - g->data = NULL;
2747 + while (g) {
2748 + struct commit_graph *next = g->base_graph;
2749 +
2750 + if (g->data)
2751 + munmap((void *)g->data, g->data_len);
2752 + free(g->filename);
2753 + free(g->bloom_filter_settings);
2754 + free(g);
2755 +
2756 + g = next;
2757 }
2762 - free(g->filename);
2763 - free(g->bloom_filter_settings);
2764 - free(g);
2758 }
2759
2760 void disable_commit_graph(struct repository *r)