branch: let delete_branches skip unmerged branches on bulk refusal

Add a skip-unmerged mode to delete_branches() and check_branch_commit() so a bulk caller can silently skip branches that are not fully merged and carry on, rather than erroring with the "use 'git branch -D'" advice that the plain "git branch -d" path emits. Existing callers are unaffected. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Harald Nordgren committed Jul 25, 2026 at 11:32 UTC 3b329696f94032f8671de0c037a86a8096cccc64
1 file changed +10 -5
builtin/branch.c
+10 -5
@@ -192,6 +192,7 @@ static int branch_merged(int kind, const char *name,
192 enum delete_branch_flags {
193 DELETE_BRANCH_FORCE = (1 << 0),
194 DELETE_BRANCH_QUIET = (1 << 1),
195 + DELETE_BRANCH_SKIP_UNMERGED = (1 << 2),
196 };
197
198 static int check_branch_commit(const char *branchname, const char *refname,
@@ -205,10 +206,13 @@ static int check_branch_commit(const char *branchname, const char *refname,
206 }
207 if (!(flags & DELETE_BRANCH_FORCE) &&
208 !branch_merged(kinds, branchname, rev, head_rev)) {
208 - error(_("the branch '%s' is not fully merged"), branchname);
209 - advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
210 - _("If you are sure you want to delete it, "
211 - "run 'git branch -D %s'"), branchname);
209 + if (!(flags & DELETE_BRANCH_SKIP_UNMERGED)) {
210 + error(_("the branch '%s' is not fully merged"),
211 + branchname);
212 + advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
213 + _("If you are sure you want to delete it, "
214 + "run 'git branch -D %s'"), branchname);
215 + }
216 return -1;
217 }
218 return 0;
@@ -315,7 +319,8 @@ static int delete_branches(int argc, const char **argv, int kinds,
319 if (!(ref_flags & (REF_ISSYMREF|REF_ISBROKEN)) &&
320 check_branch_commit(bname.buf, name, &oid, head_rev, kinds,
321 flags)) {
318 - ret = 1;
322 + if (!(flags & DELETE_BRANCH_SKIP_UNMERGED))
323 + ret = 1;
324 goto next;
325 }
326