Subject: [PATCH 14/15] name-rev: plug a memory leak in name_rev()

From: SZEDER Gábor <[email-masked]>
Date: Thu, 19 Sep 2019 23:47:09 +0200

The loop iterating over the parent commits in the name_rev() function
contains two xstrfmt() calls, and their result is leaked if the parent
commit is not processed further (because that parent has already been
visited before, and this further visit doesn't result in a better name
for its ancestors).

Make sure that the result of those xstrfmt() calls is free()d if the
parent commit is not processed further.

This results in slightly but measurably lower memory usage: the
avarage maximum resident size of 5 'git name-rev --all' invocations in
'linux.git' shrinks from 3256124kB to 319990kB, just about 2% less.

Signed-off-by: SZEDER Gábor <[email-masked]>
---
 builtin/name-rev.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index e202835129..3331075aa4 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -135,6 +135,7 @@ static void name_rev(struct commit *start_commit,
 			struct commit *parent = parents->item;
 			const char *new_name;
 			int generation, distance;
+			const char *new_name_to_free = NULL;
 
 			parse_commit(parent);
 			if (parent->date < cutoff)
@@ -154,6 +155,7 @@ static void name_rev(struct commit *start_commit,
 					new_name = xstrfmt("%.*s^%d", (int)len,
 							   name->tip_name,
 							   parent_number);
+				new_name_to_free = new_name;
 				generation = 0;
 				distance = name->distance + MERGE_TRAVERSAL_WEIGHT;
 			} else {
@@ -167,6 +169,8 @@ static void name_rev(struct commit *start_commit,
 						  from_tag))
 				last_new_parent = commit_list_append(parent,
 						  last_new_parent);
+			else
+				free((char*) new_name_to_free);
 		}
 
 		*last_new_parent = list;
-- 
2.23.0.331.g4e51dcdf11