In 2708ce62d2 (branch: sort detached HEAD based on a flag, 2021-01-07) a call to wt_status_state_free_buffers, responsible of freeing the resources that could be allocated in the local struct wt_status_state state, was eliminated. That introduced a leak that occurs with "branch list" in a detached HEAD state. The number of leaks depends on the references to "refname" in --sort and --format. With defaults, 3 are leaked: default sort is by "refname" and default format needs two references of "refname": %(refname:lstrip=2) and %(refname:rstrip-2). This doesn't leak: $ git branch --sort objectname --format '%(objectname)' This leak once: $ git branch --sort refname --format '%(refname)' This leak twice: $ git branch --sort refname --format '%(refname:lstrip=2)' Note that each different "atom" is only resolved once (see ref-filter.c). The call to wt_status_state_free_buffers was introduced in 962dd7ebc3 (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27). Bring back that call in get_head_description. Ævar Arnfjörð pointed out [1] that a similar leak is present in builtin/checkout.c:die_if_some_operation_in_progress(void), since c45f0f525de (switch: reject if some operation is in progress, 2019-03-29). The leak occurs once with "switch" while bisecting. Lets call to wc_status_state_free_buffers() there too. [1] 220926.86bkr24kjw.gmgdl@xxxxxxxxxxxxxxxxxxx Signed-off-by: Rubén Justo <rjusto@xxxxxxxxx> --- Changes since v1: - Add details about the leak - Fix the leak in builtin/checkout.c Range-diff: 1: 86b7803955 ! 1: 3fa1ddbb30 ref-filter.c: fix a leak in get_head_description @@ Commit message resources that could be allocated in the local struct wt_status_state state, was eliminated. + That introduced a leak that occurs with "branch list" in a detached HEAD + state. The number of leaks depends on the references to "refname" in + --sort and --format. With defaults, 3 are leaked: default sort is by + "refname" and default format needs two references of "refname", + %(refname:lstrip=2) and %(refname:rstrip-2). + + This doesn't leak: + $ git branch --sort objectname --format '%(objectname)' + + This leak once: + $ git branch --sort refname --format '%(refname)' + + This leak twice: + $ git branch --sort refname --format '%(refname:lstrip=2)' + + Note that each different "atom" is only resolved once (see ref-filter.c). + The call to wt_status_state_free_buffers was introduced in 962dd7ebc3 - (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27). This - commit brings back that call in get_head_description. + (wt-status: introduce wt_status_state_free_buffers(), 2020-09-27). + Bring back that call in get_head_description. + + Ævar Arnfjörð pointed out [1] that a similar leak is present in + builtin/checkout.c:die_if_some_operation_in_progress(void), since + c45f0f525de (switch: reject if some operation is in progress, + 2019-03-29). The leak ocurrs once with checkout while bisecting. + + Lets call to wc_status_state_free_buffers() there too. + + [1] 220926.86bkr24kjw.gmgdl@xxxxxxxxxxxxxxxxxxx Signed-off-by: Rubén Justo <rjusto@xxxxxxxxx> + ## builtin/checkout.c ## +@@ builtin/checkout.c: static void die_if_some_operation_in_progress(void) + "or \"git worktree add\".")); + if (state.bisect_in_progress) + warning(_("you are switching branch while bisecting")); ++ ++ wt_status_state_free_buffers(&state); + } + + static int checkout_branch(struct checkout_opts *opts, + ## ref-filter.c ## @@ ref-filter.c: char *get_head_description(void) } else builtin/checkout.c | 2 ++ ref-filter.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/builtin/checkout.c b/builtin/checkout.c index 2a132392fb..659dd5c430 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1470,6 +1470,8 @@ static void die_if_some_operation_in_progress(void) "or \"git worktree add\".")); if (state.bisect_in_progress) warning(_("you are switching branch while bisecting")); + + wt_status_state_free_buffers(&state); } static int checkout_branch(struct checkout_opts *opts, diff --git a/ref-filter.c b/ref-filter.c index fd1cb14b0f..914908fac5 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1722,6 +1722,8 @@ char *get_head_description(void) } else strbuf_addstr(&desc, _("(no branch)")); + wt_status_state_free_buffers(&state); + return strbuf_detach(&desc, NULL); } -- 2.32.0