Re: [PATCH v2] wt-status: using of wt_status_state_free_buffers
- From
Rubén Justo <rjusto@gmail.com>
- Date
- Oct 8, 2022, 00:35 UTC
- Message-ID
- <b6be0af4-8b47-d89d-13fe-a307c0e96797@gmail.com>
- In-Reply-To
- <6ff29e96-7f8d-c354-dced-b1b363e54467@gmail.com>
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@evledraar.gmail.com
Signed-off-by: Rubén Justo <rjusto@gmail.com> ---
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@evledraar.gmail.com
Signed-off-by: Rubén Justo <rjusto@gmail.com>
+ ## 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)
} elsebuiltin/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