From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
Johannes Sixt <j6t@kdbg.org>,
Phillip Wood <phillip.wood123@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v11 5/6] branch: add branch.<name>.pruneMerged opt-out
Date: Fri, 22 May 2026 11:31:37 +0000 [thread overview]
Message-ID: <75b6d2366a3aa6e8eaa3d7e657265fa3afc6ad5b.1779449498.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2285.v11.git.git.1779449498.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
Setting branch.<name>.pruneMerged=false exempts that branch from
"git branch --prune-merged". Useful for a topic branch you want
to develop further after an initial round has been merged
upstream.
Unless --quiet is given, the skip is reported per branch so the
user knows why their topic was preserved.
Explicit deletion via "git branch -d" continues to consult the
normal merge check and is not affected by this setting.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
Documentation/config/branch.adoc | 7 +++++++
Documentation/git-branch.adoc | 5 +++--
builtin/branch.c | 14 ++++++++++++++
t/t3200-branch.sh | 30 ++++++++++++++++++++++++++++++
4 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/Documentation/config/branch.adoc b/Documentation/config/branch.adoc
index a4db9fa5c8..6c1b5bb9cd 100644
--- a/Documentation/config/branch.adoc
+++ b/Documentation/config/branch.adoc
@@ -102,3 +102,10 @@ for details).
`git branch --edit-description`. Branch description is
automatically added to the `format-patch` cover letter or
`request-pull` summary.
+
+`branch.<name>.pruneMerged`::
+ If set to `false`, branch _<name>_ is exempt from
+ `git branch --prune-merged`. Useful for a topic branch you
+ intend to develop further after an initial round has been
+ merged upstream. Defaults to true. Explicit deletion via
+ `git branch -d` is unaffected.
diff --git a/Documentation/git-branch.adoc b/Documentation/git-branch.adoc
index c521b5f4ca..1bd28c4e37 100644
--- a/Documentation/git-branch.adoc
+++ b/Documentation/git-branch.adoc
@@ -226,9 +226,10 @@ the upstream refs refreshed.
+
A branch is left alone if any of the following holds:
its upstream no longer resolves locally; it is checked out in any
-worktree; or its push destination (`<branch>@{push}`) equals its
+worktree; its push destination (`<branch>@{push}`) equals its
upstream (`<branch>@{upstream}`), so it cannot be distinguished
-from a freshly pulled trunk that just looks "fully merged".
+from a freshly pulled trunk that just looks "fully merged"; or
+`branch.<name>.pruneMerged` is set to `false`.
+
Branches refused by the "fully merged" safety check are listed as
warnings and skipped; pass them to `git branch -D` explicitly if
diff --git a/builtin/branch.c b/builtin/branch.c
index 1569f29573..187d5d1563 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -875,7 +875,9 @@ static int prune_merged_branches(int argc, const char **argv, int quiet)
struct branch *branch = branch_get(short_name);
const char *upstream, *push;
struct strbuf full = STRBUF_INIT;
+ struct strbuf key = STRBUF_INIT;
int skip;
+ int opt_out;
strbuf_addf(&full, "refs/heads/%s", short_name);
skip = !!branch_checked_out(full.buf);
@@ -890,6 +892,18 @@ static int prune_merged_branches(int argc, const char **argv, int quiet)
if (!push || !strcmp(push, upstream))
continue;
+ strbuf_addf(&key, "branch.%s.prunemerged", short_name);
+ if (!repo_config_get_bool(the_repository, key.buf, &opt_out) &&
+ !opt_out) {
+ if (!quiet)
+ fprintf(stderr,
+ _("Skipping '%s' (branch.%s.pruneMerged is false)\n"),
+ short_name, short_name);
+ strbuf_release(&key);
+ continue;
+ }
+ strbuf_release(&key);
+
strvec_push(&deletable, short_name);
}
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index ad87946081..da7e174e09 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -1990,4 +1990,34 @@ test_expect_success '--prune-merged requires at least one <branch>' '
test_grep "at least one <branch>" err
'
+test_expect_success '--prune-merged honours branch.<name>.pruneMerged=false' '
+ test_when_finished "rm -rf pm-optout" &&
+ git clone pm-upstream pm-optout &&
+ git -C pm-optout remote add fork ../pm-fork &&
+ test_config -C pm-optout remote.pushDefault fork &&
+ test_config -C pm-optout push.default current &&
+ git -C pm-optout branch one one-commit &&
+ git -C pm-optout branch --set-upstream-to=origin/next one &&
+ git -C pm-optout branch two two-commit &&
+ git -C pm-optout branch --set-upstream-to=origin/next two &&
+ test_config -C pm-optout branch.one.pruneMerged false &&
+
+ git -C pm-optout branch --prune-merged "origin/*" 2>err &&
+
+ git -C pm-optout rev-parse --verify refs/heads/one &&
+ test_must_fail git -C pm-optout rev-parse --verify refs/heads/two &&
+ test_grep "Skipping .one." err
+'
+
+test_expect_success 'branch -d still deletes a pruneMerged=false branch' '
+ test_when_finished "rm -rf pm-optout-d" &&
+ git clone pm-upstream pm-optout-d &&
+ git -C pm-optout-d branch one one-commit &&
+ git -C pm-optout-d branch --set-upstream-to=origin/next one &&
+ test_config -C pm-optout-d branch.one.pruneMerged false &&
+
+ git -C pm-optout-d branch -d one &&
+ test_must_fail git -C pm-optout-d rev-parse --verify refs/heads/one
+'
+
test_done
--
gitgitgadget
next prev parent reply other threads:[~2026-05-22 11:31 UTC|newest]
Thread overview: 102+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 21:35 [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren via GitGitGadget
2026-05-03 22:39 ` Junio C Hamano
2026-05-04 18:28 ` [PATCH] checkout: add --autostash option for branch switching Harald Nordgren
2026-05-10 1:01 ` Junio C Hamano
2026-05-05 7:14 ` [PATCH] fetch: add fetch.pruneLocalBranches config Johannes Sixt
2026-05-04 18:27 ` [PATCH v2 0/6] fetch: add fetch.pruneBranches config Harald Nordgren via GitGitGadget
2026-05-04 18:27 ` [PATCH v2 1/6] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-04 23:25 ` Kristoffer Haugsbakk
2026-05-04 18:27 ` [PATCH v2 2/6] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-04 18:27 ` [PATCH v2 3/6] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-04 18:27 ` [PATCH v2 4/6] fetch: add --prune-merged Harald Nordgren via GitGitGadget
2026-05-04 18:27 ` [PATCH v2 5/6] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-04 18:27 ` [PATCH v2 6/6] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 0/6] fetch: add fetch.pruneBranches config Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 1/6] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 2/6] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 3/6] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 4/6] fetch: add --prune-merged Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 5/6] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-05 7:22 ` [PATCH v3 6/6] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 0/6] fetch: add fetch.pruneBranches config Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 1/6] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 2/6] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 3/6] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 4/6] fetch: add --prune-merged Harald Nordgren via GitGitGadget
2026-05-05 20:48 ` Johannes Sixt
2026-05-05 22:07 ` [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren
2026-05-11 2:59 ` Junio C Hamano
2026-05-11 6:56 ` Harald Nordgren
2026-05-05 19:23 ` [PATCH v4 5/6] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-05 19:23 ` [PATCH v4 6/6] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-07 20:14 ` [PATCH v4 0/6] fetch: add fetch.pruneBranches config Harald Nordgren
2026-05-11 6:58 ` [PATCH v5 0/5] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-11 6:58 ` [PATCH v5 1/5] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-11 6:58 ` [PATCH v5 2/5] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-11 8:18 ` Junio C Hamano
2026-05-11 8:44 ` [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren
2026-05-11 6:58 ` [PATCH v5 3/5] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-11 6:58 ` [PATCH v5 4/5] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-11 6:58 ` [PATCH v5 5/5] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 0/5] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 1/5] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 2/5] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 3/5] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 4/5] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-11 9:44 ` [PATCH v6 5/5] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-11 23:20 ` [PATCH v6 0/5] branch: prune-merged Junio C Hamano
2026-05-12 7:35 ` [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren
2026-05-12 8:23 ` [PATCH v7 0/5] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-12 8:23 ` [PATCH v7 1/5] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-12 8:23 ` [PATCH v7 2/5] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-12 8:23 ` [PATCH v7 3/5] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-12 13:53 ` Junio C Hamano
2026-05-12 17:00 ` [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren
2026-05-12 8:23 ` [PATCH v7 4/5] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-12 8:23 ` [PATCH v7 5/5] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 0/5] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 1/5] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 2/5] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 3/5] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 4/5] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-12 17:07 ` [PATCH v8 5/5] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-13 13:46 ` [PATCH v8 0/5] branch: prune-merged Junio C Hamano
2026-05-13 18:57 ` [PATCH] fetch: add fetch.pruneLocalBranches config Harald Nordgren
2026-05-13 19:34 ` [PATCH v9 0/5] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-13 19:34 ` [PATCH v9 1/5] branch: add --forked <remote> Harald Nordgren via GitGitGadget
2026-05-13 19:34 ` [PATCH v9 2/5] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-13 19:34 ` [PATCH v9 3/5] branch: add --prune-merged <remote> Harald Nordgren via GitGitGadget
2026-05-18 15:27 ` Phillip Wood
2026-05-21 9:46 ` Phillip Wood
2026-05-21 19:16 ` Harald Nordgren
2026-05-22 9:47 ` Phillip Wood
2026-05-22 10:51 ` Harald Nordgren
2026-05-21 12:37 ` Harald Nordgren
2026-05-21 13:29 ` Junio C Hamano
2026-05-13 19:34 ` [PATCH v9 4/5] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-13 19:34 ` [PATCH v9 5/5] branch: add --all-remotes flag Harald Nordgren via GitGitGadget
2026-05-18 15:27 ` Phillip Wood
2026-05-18 8:14 ` [PATCH v9 0/5] branch: prune-merged Harald Nordgren
2026-05-21 22:40 ` [PATCH v10 0/4] " Harald Nordgren via GitGitGadget
2026-05-21 22:40 ` [PATCH v10 1/4] branch: add --forked <branch> Harald Nordgren via GitGitGadget
2026-05-22 1:52 ` Junio C Hamano
2026-05-22 6:18 ` Johannes Sixt
2026-05-22 6:36 ` Junio C Hamano
2026-05-22 10:49 ` Harald Nordgren
2026-05-22 11:25 ` Johannes Sixt
2026-05-21 22:40 ` [PATCH v10 2/4] branch: add --prune-merged <branch> Harald Nordgren via GitGitGadget
2026-05-22 1:17 ` Junio C Hamano
2026-05-22 2:51 ` Junio C Hamano
2026-05-22 2:53 ` Junio C Hamano
2026-05-22 7:59 ` Harald Nordgren
2026-05-22 11:58 ` Junio C Hamano
2026-05-22 2:52 ` Junio C Hamano
2026-05-21 22:40 ` [PATCH v10 3/4] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-21 22:40 ` [PATCH v10 4/4] branch: add --dry-run for --prune-merged Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 0/6] branch: prune-merged Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 1/6] branch: add --forked <branch> Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 2/6] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 3/6] branch: prepare delete_branches for a bulk caller Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 4/6] branch: add --prune-merged <branch> Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` Harald Nordgren via GitGitGadget [this message]
2026-05-22 11:31 ` [PATCH v11 6/6] branch: add --dry-run for --prune-merged Harald Nordgren via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=75b6d2366a3aa6e8eaa3d7e657265fa3afc6ad5b.1779449498.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=haraldnordgren@gmail.com \
--cc=j6t@kdbg.org \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=phillip.wood123@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox