From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Harald Nordgren <haraldnordgren@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH 1/2] branch: move stacked branch helpers
Date: Tue, 25 Aug 2026 21:25:16 +0000 [thread overview]
Message-ID: <f7856e7a5b7b996be9380eb78d24c92b682a1fae.1787693117.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2365.git.git.1787693117.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
Move the stacked branch helpers earlier so delete_branches() can use
them without a forward declaration.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
builtin/branch.c | 104 +++++++++++++++++++++++------------------------
1 file changed, 52 insertions(+), 52 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index a613148fc7..87f0aa4051 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -203,6 +203,58 @@ enum delete_branch_flags {
DELETE_BRANCH_DRY_RUN = (1 << 4),
};
+struct stacked_branch_data {
+ struct strset *deletable_branch_names;
+ struct strset *protected_branch_names;
+};
+
+static int collect_stacked_branch_base(const struct reference *ref,
+ void *cb_data)
+{
+ struct stacked_branch_data *data = cb_data;
+ const char *branch_name;
+ struct branch *branch;
+ const char *upstream_refname;
+ const char *upstream_branch_name;
+
+ if (!skip_prefix(ref->name, "refs/heads/", &branch_name))
+ BUG("expected local branch ref, got '%s'", ref->name);
+ if (strset_contains(data->deletable_branch_names, branch_name))
+ return 0;
+
+ branch = branch_get(branch_name);
+ upstream_refname = branch_get_upstream(branch, NULL);
+ if (!upstream_refname ||
+ !skip_prefix(upstream_refname, "refs/heads/",
+ &upstream_branch_name) ||
+ !strset_contains(data->deletable_branch_names,
+ upstream_branch_name))
+ return 0;
+
+ strset_add(data->protected_branch_names, upstream_branch_name);
+ return 0;
+}
+
+static void protect_stacked_branch_bases(struct ref_store *refs,
+ struct strset *deletable_branch_names,
+ struct strset *protected_branch_names)
+{
+ struct stacked_branch_data data = {
+ .deletable_branch_names = deletable_branch_names,
+ .protected_branch_names = protected_branch_names,
+ };
+ struct refs_for_each_ref_options opts = {
+ .prefix = "refs/heads/",
+ };
+ struct hashmap_iter iter;
+ struct strmap_entry *entry;
+
+ refs_for_each_ref_ext(refs, collect_stacked_branch_base, &data, &opts);
+
+ strset_for_each_entry(protected_branch_names, &iter, entry)
+ strset_remove(deletable_branch_names, entry->key);
+}
+
static int check_branch_commit(const char *branchname, const char *refname,
const struct object_id *oid, struct commit *head_rev,
int kinds, unsigned int flags)
@@ -718,58 +770,6 @@ static int parse_opt_forked(const struct option *opt, const char *arg, int unset
return 0;
}
-struct stacked_branch_data {
- struct strset *deletable_branch_names;
- struct strset *protected_branch_names;
-};
-
-static int collect_stacked_branch_base(const struct reference *ref,
- void *cb_data)
-{
- struct stacked_branch_data *data = cb_data;
- const char *branch_name;
- struct branch *branch;
- const char *upstream_refname;
- const char *upstream_branch_name;
-
- if (!skip_prefix(ref->name, "refs/heads/", &branch_name))
- BUG("expected local branch ref, got '%s'", ref->name);
- if (strset_contains(data->deletable_branch_names, branch_name))
- return 0;
-
- branch = branch_get(branch_name);
- upstream_refname = branch_get_upstream(branch, NULL);
- if (!upstream_refname ||
- !skip_prefix(upstream_refname, "refs/heads/",
- &upstream_branch_name) ||
- !strset_contains(data->deletable_branch_names,
- upstream_branch_name))
- return 0;
-
- strset_add(data->protected_branch_names, upstream_branch_name);
- return 0;
-}
-
-static void protect_stacked_branch_bases(struct ref_store *refs,
- struct strset *deletable_branch_names,
- struct strset *protected_branch_names)
-{
- struct stacked_branch_data data = {
- .deletable_branch_names = deletable_branch_names,
- .protected_branch_names = protected_branch_names,
- };
- struct refs_for_each_ref_options opts = {
- .prefix = "refs/heads/",
- };
- struct hashmap_iter iter;
- struct strmap_entry *entry;
-
- refs_for_each_ref_ext(refs, collect_stacked_branch_base, &data, &opts);
-
- strset_for_each_entry(protected_branch_names, &iter, entry)
- strset_remove(deletable_branch_names, entry->key);
-}
-
static void clear_deleted_upstreams(struct strset *protected_branch_names,
struct strset *deletable_branch_names)
{
--
gitgitgadget
next prev parent reply other threads:[~2026-08-25 21:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-25 21:25 [PATCH 0/2] branch: -d protects upstream branches Harald Nordgren via GitGitGadget
2026-08-25 21:25 ` Harald Nordgren via GitGitGadget [this message]
2026-08-25 21:25 ` [PATCH 2/2] branch: protect local upstreams from -d Harald Nordgren via GitGitGadget
2026-08-25 21:59 ` Junio C Hamano
2026-08-26 6:56 ` Harald Nordgren
2026-08-26 8:46 ` Tuomas Ahola
2026-08-26 9:20 ` Harald Nordgren
2026-08-26 14:37 ` Junio C Hamano
2026-08-27 5:19 ` Elijah Newren
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=f7856e7a5b7b996be9380eb78d24c92b682a1fae.1787693117.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=haraldnordgren@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.