git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 17:16 UTC

Re: [PATCH v2] builtin/help.c: move strbuf out of help loops

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 10, 2026, 20:33 UTC
Message-ID
<xmqq1phrtoen.fsf@gitster.g>
In-Reply-To
<20260310160029.44605-1-r.siddharth.shrimali@gmail.com>
Siddharth Shrimali <r.siddharth.shrimali@gmail.com> writes:
> In list_config_help(), a strbuf was being initialized and released
> inside two separate loops. This caused unnecessary memory allocation
> and deallocation on every iteration.

OK. strbuf_init() followed by a loop that does strbuf_reset() followed by use of strbuf, concluded with strbuf_release() after leaving the loop, is a fairly common pattern to optimize such a use pattern.

> This also fixes a minor memory leak when the SHOW_CONFIG_HUMAN case
> triggers a continue.
Does it?  You are essentially saying that
	for (int i = 0; i < 10; i++) {
		struct strbuf sb = STRBUF_INIT;
 
		switch (SHOW_CONFIG_HUMAN) {
                case SHOW_CONFIG_HUMAN:
			continue;
		}
	}

leaks, but a strbuf merely initialized can safely be discarded without leaking any resources, can't it?

Show 14 quoted lines
> diff --git a/builtin/help.c b/builtin/help.c
> index 86a3d03a9b..467a0763a6 100644
> --- a/builtin/help.c
> +++ b/builtin/help.c
> @@ -134,13 +134,11 @@ static void list_config_help(enum show_config_type type)
>  	struct string_list keys = STRING_LIST_INIT_DUP;
>  	struct string_list keys_uniq = STRING_LIST_INIT_DUP;
>  	struct string_list_item *item;
> +	struct strbuf sb = STRBUF_INIT;
>  
>  	for (p = config_name_list; *p; p++) {
>  		const char *var = *p;
> -		struct strbuf sb = STRBUF_INIT;
> -

A blank between the variable declaration block and the first statement makes the code easier to follow. Loss of a blank line here is of dubious value.

>  		for (e = slot_expansions; e->prefix; e++) {
> -
This removal is good.
>  			strbuf_reset(&sb);
So we first reset, and then start building things in sb.
Show 9 quoted lines
>  			strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
>  			if (!strcasecmp(var, sb.buf)) {
> @@ -149,7 +147,6 @@ static void list_config_help(enum show_config_type type)
>  				break;
>  			}
>  		}
> -		strbuf_release(&sb);
>  		if (!e->prefix)
>  			string_list_append(&keys, var);

We no longer have to release it inside the loop, as we will reset at the beginning of the next iteration.

Show 8 quoted lines
>  	}
> @@ -164,7 +161,7 @@ static void list_config_help(enum show_config_type type)
>  		const char *var = keys.items[i].string;
>  		const char *wildcard, *tag, *cut;
>  		const char *dot = NULL;
> -		struct strbuf sb = STRBUF_INIT;
> +		strbuf_reset(&sb);
>  

The arrangement of the blank line is wrong here. The original was the last line of a declaration block which should come before the blank. Now you are removing it, and then adding a strbuf_reset() as the first statement, which should come after the blank that delimits the declarations and statements.

In any case, here we have a second loop that wants to use a scratch strbuf, so again we reset it at the beginning of the loop before we use it.

Show 8 quoted lines
>  		switch (type) {
>  		case SHOW_CONFIG_HUMAN:
> @@ -195,13 +192,13 @@ static void list_config_help(enum show_config_type type)
>  
>  		strbuf_add(&sb, var, cut - var);
>  		string_list_append(&keys_uniq, sb.buf);
> -		strbuf_release(&sb);
>  
And we no longer release it during iteration.  Instead ...
Show 6 quoted lines
>  	}
>  	string_list_clear(&keys, 0);
>  	string_list_remove_duplicates(&keys_uniq, 0);
>  	for_each_string_list_item(item, &keys_uniq)
>  		puts(item->string);
> +	strbuf_release(&sb);
... we release after we leave the loop.
>  	string_list_clear(&keys_uniq, 0);
>  }

Having looked at this patch, I recall somebody else is revamping this function already, so this patch would step on their toes. Please pay attention to what is going on in the project around the code you are touching, and coordinate with others who are working on the same code if necessary.

https://lore.kernel.org/git/20260228104654.80831-2-amishhhaaaa@gmail.com/
Thanks.
Previous: Siddharth ShrimaliNext: Siddharth Shrimali
Message 4 of 7 in “builtin/help.c: move strbuf out of help loops”
  1. builtin/help.c: move strbuf out of help loopsSiddharth Shrimali, Mar 10, 2026
  2. Patrick SteinhardtMar 10, 2026
  3. builtin/help.c: move strbuf out of help loopsSiddharth Shrimali, Mar 10, 2026
  4. Junio C HamanoMar 10, 2026
  5. Siddharth ShrimaliMar 11, 2026
  6. Amisha ChhajedMar 11, 2026
  7. Junio C HamanoMar 11, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.