From 9e86e1a05b032d712658bbe70231447455f83fb6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 19 Feb 2026 08:57:51 +0100 Subject: bisect: fix misuse of `refs_for_each_ref_in()` All callers of `refs_for_each_ref_in()` pass in a string that is terminated with a trailing slash to indicate that they only want to see refs in that specific ref hierarchy. This is in fact a requirement if one wants to use this function, as the function trims the prefix from each yielded ref. So if there was a reference that was called "refs/bisect" as in our example, the result after trimming would be the empty string, and that's something we disallow. Fix this by adding the trailing slash. Furthermore, taking a closer look, we strip the prefix only to re-add it in `mark_for_removal()`. This is somewhat roundabout, as we can instead call `refs_for_each_fullref_in()` to not do any stripping at all. Do so to simplify the code a bit. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- bisect.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'bisect.c') diff --git a/bisect.c b/bisect.c index 326b59c0dc..4f0d1a1853 100644 --- a/bisect.c +++ b/bisect.c @@ -1180,7 +1180,7 @@ int estimate_bisect_steps(int all) static int mark_for_removal(const struct reference *ref, void *cb_data) { struct string_list *refs = cb_data; - char *bisect_ref = xstrfmt("refs/bisect%s", ref->name); + char *bisect_ref = xstrdup(ref->name); string_list_append(refs, bisect_ref); return 0; } @@ -1191,9 +1191,9 @@ int bisect_clean_state(void) /* There may be some refs packed during bisection */ struct string_list refs_for_removal = STRING_LIST_INIT_NODUP; - refs_for_each_ref_in(get_main_ref_store(the_repository), - "refs/bisect", mark_for_removal, - (void *) &refs_for_removal); + refs_for_each_fullref_in(get_main_ref_store(the_repository), + "refs/bisect/", NULL, mark_for_removal, + &refs_for_removal); string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD")); string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV")); result = refs_delete_refs(get_main_ref_store(the_repository), -- cgit v1.3 From 6375a00ef16071eadbb383bd9915e277ef304bfe Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 19 Feb 2026 08:57:52 +0100 Subject: bisect: simplify string_list memory handling We declare the refs_for_removal string_list as NODUP, forcing us to manually allocate strings we insert. And then when it comes time to clean up, we set strdup_strings so that string_list_clear() will free them for us. This is a confusing pattern, and can be done much more simply by just declaring the list with the DUP initializer in the first place. It was written this way originally because one of the callsites generated the item using xstrfmt(). But that spot switched to a plain xstrdup() in the preceding commit. That means we can now just let the string_list code handle allocation itself. Signed-off-by: Jeff King Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- bisect.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'bisect.c') diff --git a/bisect.c b/bisect.c index 4f0d1a1853..268f5e36f8 100644 --- a/bisect.c +++ b/bisect.c @@ -1180,8 +1180,7 @@ int estimate_bisect_steps(int all) static int mark_for_removal(const struct reference *ref, void *cb_data) { struct string_list *refs = cb_data; - char *bisect_ref = xstrdup(ref->name); - string_list_append(refs, bisect_ref); + string_list_append(refs, ref->name); return 0; } @@ -1190,16 +1189,15 @@ int bisect_clean_state(void) int result = 0; /* There may be some refs packed during bisection */ - struct string_list refs_for_removal = STRING_LIST_INIT_NODUP; + struct string_list refs_for_removal = STRING_LIST_INIT_DUP; refs_for_each_fullref_in(get_main_ref_store(the_repository), "refs/bisect/", NULL, mark_for_removal, &refs_for_removal); - string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD")); - string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV")); + string_list_append(&refs_for_removal, "BISECT_HEAD"); + string_list_append(&refs_for_removal, "BISECT_EXPECTED_REV"); result = refs_delete_refs(get_main_ref_store(the_repository), "bisect: remove", &refs_for_removal, REF_NO_DEREF); - refs_for_removal.strdup_strings = 1; string_list_clear(&refs_for_removal, 0); unlink_or_warn(git_path_bisect_ancestors_ok()); unlink_or_warn(git_path_bisect_log()); -- cgit v1.3