From: Phillip Wood <phillip.wood123@gmail.com>
To: Jasper Mayone <me@jaspermayone.com>, git@vger.kernel.org
Cc: gitster@pobox.com, sunshine@sunshineco.com,
kristofferhaugsbakk@fastmail.com, ben.knoble@gmail.com,
haraldnordgren@gmail.com
Subject: Re: [PATCH v4 4/4] branch: do not mark the branch the current worktree is rebasing
Date: Tue, 10 Nov 2026 16:45:58 +0000 [thread overview]
Message-ID: <b0d8b454-2e7d-49a5-8d3f-030af1c3768b@gmail.com> (raw)
In-Reply-To: <20261102182930.3511-5-me@jaspermayone.com>
Hi Jasper
On 02/11/2026 18:29, Jasper Mayone wrote:
>
> diff --git a/builtin/branch.c b/builtin/branch.c
> index a613148fc7..b55a400217 100644
> --- a/builtin/branch.c
> +++ b/builtin/branch.c
> @@ -418,16 +418,28 @@ static const char *quote_literal_for_format(const char *s)
> return buf.buf;
> }
>
> -static char *build_format(struct ref_filter *filter, int maxwidth, const char *remote_prefix)
> +/*
> + * With "show_worktree" unset, the format does not mark a branch that is
> + * checked out in a worktree, nor show the path of that worktree. It is
What is "It" here
> + * used for a branch that the current worktree is rebasing or bisecting,
> + * because the "(no branch, ...)" line already names it.
I'm not sure what is being named - do you mean "it already shows the
branch name"?
In any case there are a lot of code changes here which is surprising for
what I had hoped would be a simple tweak. If we added a
'%(currentworktree)' format specifier, which should be relatively easy
as we can use the hash map of branches to checked out worktrees to look
up the worktree and check "wt->is_current" then
%(if)%(worktreepath)%(then)%(if)%(currentworktree)%(then)%(else)+
%(else) %(end)%(end)
labels checked out worktrees with "+ " if they are not the current worktree.
Thanks
Phillip
> + */
> +static char *build_format(struct ref_filter *filter, int maxwidth,
> + const char *remote_prefix, int show_worktree)
> {
> struct strbuf fmt = STRBUF_INIT;
> struct strbuf local = STRBUF_INIT;
> struct strbuf remote = STRBUF_INIT;
>
> - strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)%%(if)%%(worktreepath)%%(then)+ %s%%(else) %s%%(end)%%(end)",
> - branch_get_color(BRANCH_COLOR_CURRENT),
> - branch_get_color(BRANCH_COLOR_WORKTREE),
> - branch_get_color(BRANCH_COLOR_LOCAL));
> + if (show_worktree)
> + strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)%%(if)%%(worktreepath)%%(then)+ %s%%(else) %s%%(end)%%(end)",
> + branch_get_color(BRANCH_COLOR_CURRENT),
> + branch_get_color(BRANCH_COLOR_WORKTREE),
> + branch_get_color(BRANCH_COLOR_LOCAL));
> + else
> + strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else) %s%%(end)",
> + branch_get_color(BRANCH_COLOR_CURRENT),
> + branch_get_color(BRANCH_COLOR_LOCAL));
> strbuf_addf(&remote, " %s",
> branch_get_color(BRANCH_COLOR_REMOTE));
>
> @@ -447,8 +459,9 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
>
> if (filter->verbose > 1)
> {
> - strbuf_addf(&local, "%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)",
> - branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));
> + if (show_worktree)
> + strbuf_addf(&local, "%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)",
> + branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));
> strbuf_addf(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)"
> "%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)",
> branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));
> @@ -477,6 +490,32 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
> return strbuf_detach(&fmt, NULL);
> }
>
> +static char *current_worktree_path(void)
> +{
> + struct worktree **worktrees = get_worktrees(the_repository);
> + char *path = NULL;
> +
> + for (size_t i = 0; worktrees[i]; i++) {
> + if (worktrees[i]->is_current) {
> + path = xstrdup(worktrees[i]->path);
> + break;
> + }
> + }
> + free_worktrees(worktrees);
> + return path;
> +}
> +
> +/*
> + * Is "refname" checked out in the worktree at "here", or is that
> + * worktree rebasing or bisecting it?
> + */
> +static int checked_out_here(const char *refname, const char *here)
> +{
> + const char *path = branch_checked_out_worktree(refname);
> +
> + return path && !strcmp(path, here);
> +}
> +
> static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting,
> struct ref_format *format, struct string_list *output)
> {
> @@ -485,6 +524,9 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
> int maxwidth = 0;
> const char *remote_prefix = "";
> char *to_free = NULL;
> + struct ref_format here_format = REF_FORMAT_INIT;
> + char *here_to_free = NULL, *here = NULL;
> + struct strbuf out = STRBUF_INIT, err = STRBUF_INIT;
>
> /*
> * If we are listing more than just remote branches,
> @@ -501,39 +543,54 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
> if (filter->verbose)
> maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
>
> - if (!format->format)
> - format->format = to_free = build_format(filter, maxwidth, remote_prefix);
> + if (!format->format) {
> + format->format = to_free = build_format(filter, maxwidth,
> + remote_prefix, 1);
> + here = current_worktree_path();
> + here_format = *format;
> + here_format.format = here_to_free = build_format(filter, maxwidth,
> + remote_prefix, 0);
> + }
> format->use_color = branch_use_color;
> + here_format.use_color = branch_use_color;
>
> - if (verify_ref_format(format))
> + if (verify_ref_format(format) ||
> + (here && verify_ref_format(&here_format)))
> die(_("unable to parse format string"));
>
> filter_ahead_behind(the_repository, &array);
> ref_array_sort(sorting, &array);
>
> - if (column_active(colopts)) {
> - struct strbuf out = STRBUF_INIT, err = STRBUF_INIT;
> -
> + if (column_active(colopts))
> assert(!filter->verbose && "--column and --verbose are incompatible");
>
> - for (i = 0; i < array.nr; i++) {
> - strbuf_reset(&err);
> - strbuf_reset(&out);
> - if (format_ref_array_item(array.items[i], format, &out, &err))
> - die("%s", err.buf);
> + for (i = 0; i < array.nr; i++) {
> + struct ref_array_item *item = array.items[i];
> + struct ref_format *f = format;
>
> + if (here && checked_out_here(item->refname, here))
> + f = &here_format;
> +
> + strbuf_reset(&err);
> + strbuf_reset(&out);
> + if (format_ref_array_item(item, f, &out, &err))
> + die("%s", err.buf);
> +
> + if (column_active(colopts))
> /* format to a string_list to let print_columns() do its job */
> string_list_append(output, out.buf);
> + else if (out.len || !format->array_opts.omit_empty) {
> + fwrite(out.buf, 1, out.len, stdout);
> + putchar('\n');
> }
> -
> - strbuf_release(&err);
> - strbuf_release(&out);
> - } else {
> - print_formatted_ref_array(&array, format);
> }
>
> + strbuf_release(&err);
> + strbuf_release(&out);
> ref_array_clear(&array);
> free(to_free);
> + free(here_to_free);
> + free(here);
> }
>
> static void print_current_branch_name(void)
> diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
> index debfac5f26..5541f1429b 100755
> --- a/t/t3203-branch-output.sh
> +++ b/t/t3203-branch-output.sh
> @@ -456,6 +456,23 @@ test_expect_success 'branch being rebased in a worktree is marked' '
> test_cmp expect actual
> '
>
> +test_expect_success 'branch being rebased is not marked in its own worktree' '
> + test_when_finished "git -C rebase_dir rebase --abort; rm -rf rebase_dir; git worktree prune; git branch -D rebasing" &&
> + git worktree add -b rebasing rebase_dir branch-two &&
> + (
> + cd rebase_dir &&
> + git commit --allow-empty -m rebase-me &&
> + test_must_fail git rebase -f -x false HEAD~1 &&
> + git branch --list rebasing >actual &&
> + echo " rebasing" >expect &&
> + test_cmp expect actual &&
> + git branch -vv --list rebasing >actual &&
> + test_grep ! "$(pwd)" actual &&
> + git branch >actual &&
> + test_grep "^\* (no branch, rebasing rebasing)" actual
> + )
> +'
> +
> test_expect_success 'branch being bisected in a worktree is marked' '
> test_when_finished "git -C bisect_dir bisect reset; rm -rf bisect_dir; git worktree prune; git branch -D bisecting" &&
> git worktree add -b bisecting bisect_dir branch-two &&
> @@ -464,7 +481,10 @@ test_expect_success 'branch being bisected in a worktree is marked' '
> git commit --allow-empty -m bisect-one &&
> git commit --allow-empty -m bisect-two &&
> git bisect start HEAD HEAD~2 &&
> - test_must_fail git symbolic-ref -q HEAD
> + test_must_fail git symbolic-ref -q HEAD &&
> + git branch --list bisecting >actual &&
> + echo " bisecting" >expect &&
> + test_cmp expect actual
> ) &&
> git branch --list bisecting >actual &&
> echo "+ bisecting" >expect &&
next prev parent reply other threads:[~2026-11-10 16:46 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 17:33 [RFC PATCH 0/1] worktree list: add --merged and --no-merged Jasper Mayone
2026-10-21 17:33 ` [RFC PATCH 1/1] " Jasper Mayone
2026-10-23 18:30 ` Junio C Hamano
2026-10-24 6:25 ` Eric Sunshine
2026-10-24 16:53 ` [PATCH v2] worktree list: add --branch to select worktrees by branch Jasper Mayone
2026-10-25 14:47 ` Phillip Wood
2026-10-26 11:02 ` Phillip Wood
2026-10-28 6:02 ` Eric Sunshine
2026-10-28 15:27 ` Junio C Hamano
2026-10-28 11:32 ` Kristoffer Haugsbakk
2026-10-29 4:46 ` Jasper Mayone
2026-10-29 5:01 ` Eric Sunshine
2026-10-29 11:14 ` Phillip Wood
2026-10-29 14:23 ` Ben Knoble
2026-10-29 16:10 ` Phillip Wood
2026-10-30 14:21 ` [PATCH 0/2] worktree: treat a branch being rebased or bisected as checked out Jasper Mayone
2026-10-30 14:21 ` [PATCH 1/2] worktree remove: refuse a worktree in the middle of a rebase or bisect Jasper Mayone
2026-11-02 14:07 ` Phillip Wood
2026-11-02 17:57 ` Jasper Mayone
2026-10-30 14:21 ` [PATCH 2/2] ref-filter: name the worktree of a branch being rebased or bisected Jasper Mayone
2026-11-02 14:06 ` Phillip Wood
2026-11-02 17:57 ` Jasper Mayone
2026-10-30 22:55 ` [PATCH 0/2] worktree: treat a branch being rebased or bisected as checked out Junio C Hamano
2026-10-30 23:06 ` Jasper Mayone
2026-11-02 18:29 ` [PATCH v4 0/4] " Jasper Mayone
2026-11-02 18:29 ` [PATCH v4 1/4] worktree remove: refuse a worktree in the middle of an operation Jasper Mayone
2026-11-10 16:47 ` Phillip Wood
2026-11-10 17:09 ` Ben Knoble
2026-11-02 18:29 ` [PATCH v4 2/4] doc: for-each-ref: say how to read %(worktreepath) safely Jasper Mayone
2026-11-09 12:36 ` D. Ben Knoble
2026-11-09 15:10 ` Phillip Wood
2026-11-09 17:27 ` Ben Knoble
2026-11-09 20:17 ` Junio C Hamano
2026-11-10 16:47 ` Phillip Wood
2026-11-02 18:29 ` [PATCH v4 3/4] ref-filter: name the worktree of a branch being rebased or bisected Jasper Mayone
2026-11-10 16:47 ` Phillip Wood
2026-11-02 18:29 ` [PATCH v4 4/4] branch: do not mark the branch the current worktree is rebasing Jasper Mayone
2026-11-10 16:45 ` Phillip Wood [this message]
2026-11-10 16:49 ` [PATCH v4 0/4] worktree: treat a branch being rebased or bisected as checked out Phillip Wood
2026-11-11 15:28 ` [PATCH v5 0/5] " Jasper Mayone
2026-11-11 15:28 ` [PATCH v5 1/5] worktree remove: refuse a worktree in the middle of an operation Jasper Mayone
2026-11-11 15:28 ` [PATCH v5 2/5] doc: for-each-ref: say how to read %(worktreepath) safely Jasper Mayone
2026-11-11 15:28 ` [PATCH v5 3/5] ref-filter: name the worktree of a branch being rebased or bisected Jasper Mayone
2026-11-11 15:28 ` [PATCH v5 4/5] ref-filter: add %(currentworktree) Jasper Mayone
2026-11-11 15:28 ` [PATCH v5 5/5] branch: do not mark the branch the current worktree is rebasing Jasper Mayone
2026-11-11 15:42 ` [PATCH v5 0/5] worktree: treat a branch being rebased or bisected as checked out Ben Knoble
2026-10-21 21:36 ` [RFC PATCH 0/1] worktree list: add --merged and --no-merged Harald Nordgren
2026-10-21 22:12 ` Junio C Hamano
2026-10-22 7:21 ` Harald Nordgren
2026-10-22 17:58 ` Kristoffer Haugsbakk
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=b0d8b454-2e7d-49a5-8d3f-030af1c3768b@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=ben.knoble@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=haraldnordgren@gmail.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=me@jaspermayone.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=sunshine@sunshineco.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