[PATCH] branch: avoid slow strvec Coccinelle matching
From: <hidden>
Date: 2026-07-24 09:11:54
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Ted Nyman <redacted> The --delete-merged implementation declares a loop index at function scope and reuses it to walk its strvec of upstreams and its list of candidate branches. Coccinelle 1.1.1 spends hours matching this against the separate_loop_index rule in tools/coccinelle/strvec.cocci, causing the static-analysis job on 'seen' to reach its six-hour timeout. Declare each index in its for loop instead. This avoids the expensive separate-index rule, limits each index to the loop that uses it, and leaves the branch deletion behavior unchanged. Signed-off-by: Ted Nyman <redacted> --- This applies on top of hn/branch-delete-merged and addresses the long static-analysis runs on 'seen'. Coccinelle 1.1.1 spends hours matching the existing separate_loop_index rule against delete_merged_branches(). Declare each loop index in its for statement instead of sharing an index declared at function scope. This avoids the pathological matching without changing branch behavior. The CI failure reproduces locally with Coccinelle 1.1.1: applying strvec.cocci to the original builtin/branch.c still times out with "spatch --timeout 120". With this change, the same check completes in 0.06 seconds. The full coccicheck run completes in 47 seconds, and all 190 tests in t3200-branch.sh pass with a fresh DEVELOPER=1 build. builtin/branch.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 42f2221547..2415a275ea 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c@@ -797,10 +797,9 @@ static int delete_merged_branches(const struct strvec *upstreams, struct strbuf key = STRBUF_INIT; struct hashmap_iter iter; struct strmap_entry *entry; - size_t i; int ret = 0; - for (i = 0; i < upstreams->nr; i++) + for (size_t i = 0; i < upstreams->nr; i++) if (ref_filter_forked_add(&filter, upstreams->v[i]) < 0) die(_("'%s' is not a valid branch or pattern"), upstreams->v[i]);
@@ -809,7 +808,7 @@ static int delete_merged_branches(const struct strvec *upstreams, filter.name_patterns = argv; filter_refs(&candidates, &filter, filter.kind); - for (i = 0; i < (size_t)candidates.nr; i++) { + for (size_t i = 0; i < (size_t)candidates.nr; i++) { const char *branch_refname = candidates.items[i]->refname; const char *branch_name; struct branch *branch;
--
2.54.0.8.g047e0526de