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 v12 1/6] branch: add --forked filter for --list mode
Date: Wed, 03 Jun 2026 09:04:34 +0000 [thread overview]
Message-ID: <8834c424fbd27800636fe21ae73e9cdce75b558a.1780477479.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2285.v12.git.git.1780477479.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
Add a --forked option to "git branch" list mode that keeps only
branches whose configured upstream matches <branch>. The argument
can be a ref (e.g. "origin/main", "master") or a shell-style
glob (e.g. "origin/*"). The option can be repeated to widen the
filter.
Because it is a filter on list mode, --forked composes with the
existing list-mode filters, so
git branch --merged origin/main --forked 'origin/*'
lists branches forked from origin that have already been
integrated into origin/main, and --no-merged inverts the question.
This is the building block for --prune-merged, which deletes the
listed branches once they have landed on their upstream.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
Documentation/git-branch.adoc | 7 ++
builtin/branch.c | 147 +++++++++++++++++++++++++++++++++-
ref-filter.c | 10 +--
ref-filter.h | 2 +
t/t3200-branch.sh | 92 +++++++++++++++++++++
5 files changed, 249 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-branch.adoc b/Documentation/git-branch.adoc
index c0afddc424..8002d7f38c 100644
--- a/Documentation/git-branch.adoc
+++ b/Documentation/git-branch.adoc
@@ -14,6 +14,7 @@ git branch [--color[=<when>] | --no-color] [--show-current]
[--merged [<commit>]] [--no-merged [<commit>]]
[--contains [<commit>]] [--no-contains [<commit>]]
[--points-at <object>] [--format=<format>]
+ [(--forked <branch>)...]
[(-r|--remotes) | (-a|--all)]
[--list] [<pattern>...]
git branch [--track[=(direct|inherit)] | --no-track] [-f]
@@ -199,6 +200,12 @@ This option is only applicable in non-verbose mode.
Print the name of the current branch. In detached `HEAD` state,
nothing is printed.
+`--forked <branch>`::
+ List only branches whose configured upstream matches
+ _<branch>_. The argument can be a ref (e.g. `origin/main`,
+ `master`) or a shell-style glob (e.g. `'origin/*'`). The
+ option can be repeated to widen the filter.
+
`-v`::
`-vv`::
`--verbose`::
diff --git a/builtin/branch.c b/builtin/branch.c
index 1572a4f9ef..12711b29cf 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -28,9 +28,10 @@
#include "help.h"
#include "advice.h"
#include "commit-reach.h"
+#include "wildmatch.h"
static const char * const builtin_branch_usage[] = {
- N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"),
+ N_("git branch [<options>] [-r | -a] [--merged] [--no-merged] [(--forked <branch>)...]"),
N_("git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-point>]"),
N_("git branch [<options>] [-l] [<pattern>...]"),
N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
@@ -442,8 +443,12 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
return strbuf_detach(&fmt, NULL);
}
+static void filter_array_by_forked(struct ref_array *array,
+ const struct string_list *upstreams);
+
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting,
- struct ref_format *format, struct string_list *output)
+ struct ref_format *format, struct string_list *output,
+ const struct string_list *forked_upstreams)
{
int i;
struct ref_array array;
@@ -463,6 +468,9 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
filter_refs(&array, filter, filter->kind);
+ if (forked_upstreams->nr)
+ filter_array_by_forked(&array, forked_upstreams);
+
if (filter->verbose)
maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
@@ -673,6 +681,131 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
free_worktrees(worktrees);
}
+struct upstream_pattern {
+ char *name;
+ int is_wildcard;
+};
+
+static void upstream_pattern_list_clear(struct upstream_pattern *items,
+ size_t nr)
+{
+ size_t i;
+ for (i = 0; i < nr; i++)
+ free(items[i].name);
+ free(items);
+}
+
+static const char *short_upstream_name(const char *full_ref)
+{
+ const char *short_name = full_ref;
+ (void)(skip_prefix(short_name, "refs/heads/", &short_name) ||
+ skip_prefix(short_name, "refs/remotes/", &short_name));
+ return short_name;
+}
+
+static int parse_one_forked_arg(const char *arg, struct upstream_pattern *out)
+{
+ struct object_id oid;
+ char *full_ref = NULL;
+
+ if (has_glob_specials(arg)) {
+ out->name = xstrdup(arg);
+ out->is_wildcard = 1;
+ return 0;
+ }
+
+ if (repo_dwim_ref(the_repository, arg, strlen(arg), &oid,
+ &full_ref, 0) == 1 &&
+ (starts_with(full_ref, "refs/heads/") ||
+ starts_with(full_ref, "refs/remotes/"))) {
+ out->name = xstrdup(short_upstream_name(full_ref));
+ out->is_wildcard = 0;
+ free(full_ref);
+ return 0;
+ }
+ free(full_ref);
+ return -1;
+}
+
+static void parse_forked_args(const struct string_list *args,
+ struct upstream_pattern **patterns_out,
+ size_t *nr_out)
+{
+ struct upstream_pattern *patterns;
+ size_t i;
+
+ ALLOC_ARRAY(patterns, args->nr);
+ for (i = 0; i < args->nr; i++) {
+ const char *arg = args->items[i].string;
+ if (parse_one_forked_arg(arg, &patterns[i]) < 0) {
+ upstream_pattern_list_clear(patterns, i);
+ die(_("'%s' is not a valid branch or pattern"), arg);
+ }
+ }
+ *patterns_out = patterns;
+ *nr_out = args->nr;
+}
+
+static int upstream_matches(const char *short_upstream,
+ const struct upstream_pattern *patterns,
+ size_t nr)
+{
+ size_t i;
+
+ for (i = 0; i < nr; i++) {
+ const struct upstream_pattern *p = &patterns[i];
+ if (p->is_wildcard) {
+ if (!wildmatch(p->name, short_upstream, WM_PATHNAME))
+ return 1;
+ } else if (!strcmp(p->name, short_upstream)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int branch_upstream_matches(const char *full_refname,
+ const struct upstream_pattern *patterns,
+ size_t nr_patterns)
+{
+ const char *short_name;
+ struct branch *branch;
+ const char *upstream;
+
+ if (!skip_prefix(full_refname, "refs/heads/", &short_name))
+ return 0;
+ branch = branch_get(short_name);
+ if (!branch)
+ return 0;
+ upstream = branch_get_upstream(branch, NULL);
+ if (!upstream)
+ return 0;
+ return upstream_matches(short_upstream_name(upstream),
+ patterns, nr_patterns);
+}
+
+static void filter_array_by_forked(struct ref_array *array,
+ const struct string_list *upstreams)
+{
+ struct upstream_pattern *patterns = NULL;
+ size_t nr_patterns = 0;
+ int i, kept = 0;
+
+ parse_forked_args(upstreams, &patterns, &nr_patterns);
+
+ for (i = 0; i < array->nr; i++) {
+ struct ref_array_item *item = array->items[i];
+ if (branch_upstream_matches(item->refname,
+ patterns, nr_patterns))
+ array->items[kept++] = item;
+ else
+ free_ref_array_item(item);
+ }
+ array->nr = kept;
+
+ upstream_pattern_list_clear(patterns, nr_patterns);
+}
+
static GIT_PATH_FUNC(edit_description, "EDIT_DESCRIPTION")
static int edit_branch_description(const char *branch_name)
@@ -714,6 +847,7 @@ int cmd_branch(int argc,
/* possible actions */
int delete = 0, rename = 0, copy = 0, list = 0,
unset_upstream = 0, show_current = 0, edit_description = 0;
+ struct string_list forked_upstreams = STRING_LIST_INIT_DUP;
const char *new_upstream = NULL;
int noncreate_actions = 0;
/* possible options */
@@ -767,6 +901,8 @@ int cmd_branch(int argc,
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
N_("edit the description for the branch")),
+ OPT_STRING_LIST(0, "forked", &forked_upstreams, N_("branch"),
+ N_("list local branches whose upstream matches <branch> (repeatable)")),
OPT__FORCE(&force, N_("force creation, move/rename, deletion"), PARSE_OPT_NOCOMPLETE),
OPT_MERGED(&filter, N_("print only branches that are merged")),
OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
@@ -815,7 +951,8 @@ int cmd_branch(int argc,
list = 1;
if (filter.with_commit || filter.no_commit ||
- filter.reachable_from || filter.unreachable_from || filter.points_at.nr)
+ filter.reachable_from || filter.unreachable_from ||
+ filter.points_at.nr || forked_upstreams.nr)
list = 1;
noncreate_actions = !!delete + !!rename + !!copy + !!new_upstream +
@@ -880,7 +1017,8 @@ int cmd_branch(int argc,
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
ref_sorting_set_sort_flags_all(
sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1);
- print_ref_list(&filter, sorting, &format, &output);
+ print_ref_list(&filter, sorting, &format, &output,
+ &forked_upstreams);
print_columns(&output, colopts, NULL);
string_list_clear(&output, 0);
ref_sorting_release(sorting);
@@ -1020,5 +1158,6 @@ int cmd_branch(int argc,
out:
string_list_clear(&sorting_options, 0);
+ string_list_clear(&forked_upstreams, 0);
return ret;
}
diff --git a/ref-filter.c b/ref-filter.c
index 1da4c0e60d..65e7bc6785 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -3035,7 +3035,7 @@ static int filter_one(const struct reference *ref, void *cb_data)
}
/* Free memory allocated for a ref_array_item */
-static void free_array_item(struct ref_array_item *item)
+void free_ref_array_item(struct ref_array_item *item)
{
free((char *)item->symref);
if (item->value) {
@@ -3078,7 +3078,7 @@ static int filter_and_format_one(const struct reference *ref, void *cb_data)
strbuf_release(&output);
strbuf_release(&err);
- free_array_item(item);
+ free_ref_array_item(item);
/*
* Increment the running count of refs that match the filter. If
@@ -3098,7 +3098,7 @@ void ref_array_clear(struct ref_array *array)
int i;
for (i = 0; i < array->nr; i++)
- free_array_item(array->items[i]);
+ free_ref_array_item(array->items[i]);
FREE_AND_NULL(array->items);
array->nr = array->alloc = 0;
@@ -3171,7 +3171,7 @@ static void reach_filter(struct ref_array *array,
if (is_merged == include_reached)
array->items[array->nr++] = array->items[i];
else
- free_array_item(item);
+ free_ref_array_item(item);
}
clear_commit_marks_many(old_nr, to_clear, ALL_REV_FLAGS);
@@ -3667,7 +3667,7 @@ void pretty_print_ref(const char *name, const struct object_id *oid,
strbuf_release(&err);
strbuf_release(&output);
- free_array_item(ref_item);
+ free_ref_array_item(ref_item);
}
static int parse_sorting_atom(const char *atom)
diff --git a/ref-filter.h b/ref-filter.h
index 120221b47f..3883b9dc62 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -155,6 +155,8 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type,
struct ref_format *format);
/* Clear all memory allocated to ref_array */
void ref_array_clear(struct ref_array *array);
+/* Free a single item from a ref_array */
+void free_ref_array_item(struct ref_array_item *item);
/* Used to verify if the given format is correct and to parse out the used atoms */
int verify_ref_format(struct ref_format *format);
/* Sort the given ref_array as per the ref_sorting provided */
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index e7829c2c4b..4e7deddc04 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -1717,4 +1717,96 @@ test_expect_success 'errors if given a bad branch name' '
test_cmp expect actual
'
+test_expect_success '--forked: setup' '
+ test_create_repo forked-upstream &&
+ test_commit -C forked-upstream base &&
+ git -C forked-upstream branch one base &&
+ git -C forked-upstream branch two base &&
+
+ test_create_repo forked-other &&
+ test_commit -C forked-other other-base &&
+ git -C forked-other branch foreign other-base &&
+
+ git clone forked-upstream forked &&
+ git -C forked remote add other ../forked-other &&
+ git -C forked fetch other &&
+ git -C forked branch local-base &&
+ git -C forked branch --track local-one origin/one &&
+ git -C forked branch --track local-two origin/two &&
+ git -C forked branch --track local-foreign other/foreign &&
+ git -C forked branch detached &&
+ git -C forked branch --track local-trunk local-base
+'
+
+test_expect_success '--forked <upstream-tracking-branch> filters by upstream' '
+ git -C forked branch --forked origin/one --format="%(refname:short)" >actual &&
+ echo local-one >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--forked <glob> filters by wildmatch' '
+ git -C forked branch --forked "origin/*" --format="%(refname:short)" >actual &&
+ cat >expect <<-\EOF &&
+ local-one
+ local-two
+ main
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success '--forked <local-branch> matches branches with local upstream' '
+ git -C forked branch --forked local-base --format="%(refname:short)" >actual &&
+ echo local-trunk >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--forked can be repeated to widen the filter' '
+ git -C forked branch --forked origin/one --forked other/foreign --format="%(refname:short)" >actual &&
+ cat >expect <<-\EOF &&
+ local-foreign
+ local-one
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success '--forked combines literal and glob arguments' '
+ git -C forked branch --forked local-base --forked "other/*" --format="%(refname:short)" >actual &&
+ cat >expect <<-\EOF &&
+ local-foreign
+ local-trunk
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success '--forked "*/*" covers every remote-tracking upstream' '
+ git -C forked branch --forked "*/*" --format="%(refname:short)" >actual &&
+ cat >expect <<-\EOF &&
+ local-foreign
+ local-one
+ local-two
+ main
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success '--forked composes with --no-merged' '
+ test_when_finished "git -C forked checkout detached" &&
+ git -C forked checkout local-one &&
+ test_commit -C forked local-only &&
+ git -C forked branch --forked "origin/*" --no-merged origin/one \
+ --format="%(refname:short)" >actual &&
+ echo local-one >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--forked rejects unknown branch/pattern' '
+ test_must_fail git -C forked branch --forked nope 2>err &&
+ test_grep "not a valid branch or pattern" err
+'
+
+test_expect_success '--forked requires a value' '
+ test_must_fail git -C forked branch --forked 2>err &&
+ test_grep "requires a value" err
+'
+
test_done
--
gitgitgadget
next prev parent reply other threads:[~2026-06-03 9:04 UTC|newest]
Thread overview: 111+ 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 ` [PATCH v11 5/6] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-05-22 11:31 ` [PATCH v11 6/6] branch: add --dry-run for --prune-merged Harald Nordgren via GitGitGadget
2026-06-02 13:05 ` [PATCH v11 0/6] branch: prune-merged Phillip Wood
2026-06-02 13:41 ` Harald Nordgren
2026-06-03 9:04 ` [PATCH v12 " Harald Nordgren via GitGitGadget
2026-06-03 9:04 ` Harald Nordgren via GitGitGadget [this message]
2026-06-03 9:04 ` [PATCH v12 2/6] branch: let delete_branches warn instead of error on bulk refusal Harald Nordgren via GitGitGadget
2026-06-03 9:04 ` [PATCH v12 3/6] branch: prepare delete_branches for a bulk caller Harald Nordgren via GitGitGadget
2026-06-03 9:04 ` [PATCH v12 4/6] branch: add --prune-merged <branch> Harald Nordgren via GitGitGadget
2026-06-03 9:04 ` [PATCH v12 5/6] branch: add branch.<name>.pruneMerged opt-out Harald Nordgren via GitGitGadget
2026-06-03 9:04 ` [PATCH v12 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=8834c424fbd27800636fe21ae73e9cdce75b558a.1780477479.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