line-log: get rid of the parents array in process_ranges_merge_commit()

We can easily iterate through the parents of a merge commit without turning the list of parents into a dynamically allocated array of parents, so let's do so. This way we can avoid a memory allocation for each processed merge commit, though its effect on runtime seems to be unmeasurable. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

SZEDER Gábor committed Aug 24, 2025 at 21:06 UTC 9df27c258edf89ea8ea0472a0a9c260e026f197f
1 file changed +12 -12
line-log.c
+12 -12
@@ -1203,7 +1203,6 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1203 struct line_log_data *range)
1204 {
1205 struct line_log_data **cand;
1206 - struct commit **parents;
1206 struct commit_list *p;
1207 int i;
1208 int nparents = commit_list_count(commit->parents);
@@ -1213,15 +1212,15 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1212 nparents = 1;
1213
1214 CALLOC_ARRAY(cand, nparents);
1216 - ALLOC_ARRAY(parents, nparents);
1215
1218 - p = commit->parents;
1219 - for (i = 0; i < nparents; i++) {
1216 + for (p = commit->parents, i = 0;
1217 + p && i < nparents;
1218 + p = p->next, i++) {
1219 + struct commit *parent = p->item;
1220 struct diff_queue_struct diffqueue = DIFF_QUEUE_INIT;
1221 int changed;
1222 - parents[i] = p->item;
1223 - p = p->next;
1224 - queue_diffs(range, &rev->diffopt, &diffqueue, commit, parents[i]);
1222 +
1223 + queue_diffs(range, &rev->diffopt, &diffqueue, commit, parent);
1224
1225 changed = process_all_files(&cand[i], rev, &diffqueue, range);
1226 diff_queue_clear(&diffqueue);
@@ -1230,9 +1229,9 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1229 * This parent can take all the blame, so we
1230 * don't follow any other path in history
1231 */
1233 - add_line_range(rev, parents[i], cand[i]);
1232 + add_line_range(rev, parent, cand[i]);
1233 free_commit_list(commit->parents);
1235 - commit_list_append(parents[i], &commit->parents);
1234 + commit_list_append(parent, &commit->parents);
1235
1236 ret = 0;
1237 goto out;
@@ -1243,14 +1242,15 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1242 * No single parent took the blame. We add the candidates
1243 * from the above loop to the parents.
1244 */
1246 - for (i = 0; i < nparents; i++)
1247 - add_line_range(rev, parents[i], cand[i]);
1245 + for (p = commit->parents, i = 0;
1246 + p && i < nparents;
1247 + p = p->next, i++)
1248 + add_line_range(rev, p->item, cand[i]);
1249
1250 ret = 1;
1251
1252 out:
1253 clear_commit_line_range(rev, commit);
1253 - free(parents);
1254 for (i = 0; i < nparents; i++) {
1255 if (!cand[i])
1256 continue;