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>
This commit is contained in:
Harald Nordgren
2026-06-15 16:47:18 +00:00
committed by Junio C Hamano
parent 35529797af
commit 01e3fc772f

View File

@@ -192,6 +192,7 @@ static int branch_merged(int kind, const char *name,
enum delete_branch_flags {
DELETE_BRANCH_FORCE = (1 << 0),
DELETE_BRANCH_QUIET = (1 << 1),
DELETE_BRANCH_SKIP_UNMERGED = (1 << 2),
};
static int check_branch_commit(const char *branchname, const char *refname,
@@ -199,16 +200,20 @@ static int check_branch_commit(const char *branchname, const char *refname,
int kinds, unsigned int flags)
{
bool force = flags & DELETE_BRANCH_FORCE;
bool skip_unmerged = flags & DELETE_BRANCH_SKIP_UNMERGED;
struct commit *rev = lookup_commit_reference(the_repository, oid);
if (!force && !rev) {
error(_("couldn't look up commit object for '%s'"), refname);
return -1;
}
if (!force && !branch_merged(kinds, branchname, rev, head_rev)) {
error(_("the branch '%s' is not fully merged"), branchname);
advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
_("If you are sure you want to delete it, "
"run 'git branch -D %s'"), branchname);
if (!skip_unmerged) {
error(_("the branch '%s' is not fully merged"),
branchname);
advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
_("If you are sure you want to delete it, "
"run 'git branch -D %s'"), branchname);
}
return -1;
}
return 0;
@@ -235,6 +240,7 @@ static int delete_branches(int argc, const char **argv, int kinds,
int remote_branch = 0;
bool force;
bool quiet = flags & DELETE_BRANCH_QUIET;
bool skip_unmerged = flags & DELETE_BRANCH_SKIP_UNMERGED;
struct strbuf bname = STRBUF_INIT;
enum interpret_branch_kind allowed_interpret;
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
@@ -319,7 +325,8 @@ static int delete_branches(int argc, const char **argv, int kinds,
if (!(ref_flags & (REF_ISSYMREF|REF_ISBROKEN)) &&
check_branch_commit(bname.buf, name, &oid, head_rev, kinds,
flags)) {
ret = 1;
if (!skip_unmerged)
ret = 1;
goto next;
}