git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/3] checkout: provide hint when failing due to another worktree

From
KHKristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>
Date
Sep 13, 2025, 20:55 UTC
Message-ID
<be510685-3be1-4f71-806a-6b580bb1cf21@app.fastmail.com>
In-Reply-To
<20250913141327.2775228-2-gabriel.scherer@inria.fr>
Unrelated: I found it confusing that my `co = checkout` alias did not
work with this fresh-off-the-press Advice:[1]

``` $ ./git co master fatal: 'master' is already used by worktree at '<path>' $ ./git checkout master fatal: 'master' is already used by worktree at '<patch>' hint: Use --detach to avoid this restriction, hint: or --ignore-other-worktrees to ignore it. hint: Disable this message with "git config set advice.branchUsedInOtherWorktree false" ```

But it did for this older Advice (which is in my installed git(1)):

``` $ ./git co -b .. @ fatal: '..' is not a valid branch name hint: See `man git check-ref-format` hint: Disable this message with "git config set advice.refSyntax false" ```

It’s because aliases are run as a subprocess from the `git` in `PATH`:

``` strvec_push(&cmd.args, "git"); ```

[1]: Chain of events:
1. Try to trigger the Advice in this series
2. ... but it doesn’t
3. Is the code wrong?
4. Wait, I’m using my alias (which I always use; I don’t think about it)
5. I test with `git checkout`: it works
6. ... so aliases don’t work with Advice?
7. Test an existing Advice that I know about
8. ... but it does work with aliases
9.–15. ...
It was part of the process.  I didn’t *decide* to get hung up on it. ;)
On Sat, Sep 13, 2025, at 16:13, Gabriel Scherer wrote:
Show 5 quoted lines
> From: "Gabriel.Scherer" <gabriel.scherer@inria.fr>
>
> When checkout/switch fails because the target branch is already used
> by another worktree, we now hint that the user could use --detach or
> --ignore-other-worktrees.

The commit message is supposed to discuss what the code does without the patch in the present tense. What the patch does is in the imperative mood. Refer to `Documentation/SubmittingPatches`, “imperative mood”.

Maybe there should be a paragraph which motivates the need for an Advice and these two in particular? You could also concievably advise removing the worktree. :)

> Note: this error can also happen on rebase, which unfortunately does
> not support --ignore-other-worktrees. We do not show advice in this
> case, and leave 'rebase --ignore-other-worktrees' to future work.

After reading this I thought this was not handled by this patch series. But you add the this option to git-rebase(1) in the second patch.

“Future work” suggests to me something ranging from:

• there is another patch series that deal with this; or • there are no plans to do this (but it could be done in theory).

Show 23 quoted lines
>
> Signed-off-by: Gabriel Scherer <gabriel.scherer@inria.fr>
> ---
>  Documentation/config/advice.adoc |  3 +++
>  advice.c                         |  1 +
>  advice.h                         |  1 +
>  branch.c                         | 13 +++++++++++--
>  branch.h                         |  4 ++++
>  builtin/checkout.c               | 12 ++++++++++--
>  6 files changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/config/advice.adoc
> b/Documentation/config/advice.adoc
> index 257db58918..9ee64f44ea 100644
> --- a/Documentation/config/advice.adoc
> +++ b/Documentation/config/advice.adoc
> @@ -27,6 +27,9 @@ all advice messages.
>  		Shown when a fetch refspec for multiple remotes maps to
>  		the same remote-tracking branch namespace and causes branch
>  		tracking set-up to fail.
> +	branchUsedInOtherWorktree::
> +		Shown when the user attemps to switch to a branch
> +		that is already checked out in another worktree.

This maintains sort-order which is good. It is also consistent in all points with 95c987e6fad (advice: make all entries stylistically consistent, 2024-03-05) for what it’s worth.

I also think the wording/formulation is great.
Show 12 quoted lines
>  	checkoutAmbiguousRemoteBranchName::
>  		Shown when the argument to
>  		linkgit:git-checkout[1] and linkgit:git-switch[1]
> diff --git a/advice.c b/advice.c
> index e5f0ff8449..5c9b763472 100644
> --- a/advice.c
> +++ b/advice.c
> @@ -50,6 +50,7 @@ static struct {
>  	[ADVICE_AMBIGUOUS_FETCH_REFSPEC]		= { "ambiguousFetchRefspec" },
>  	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir" },
>  	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName" },
> +	[ADVICE_BRANCH_USED_IN_OTHER_WORKTREE]		= { "branchUsedInOtherWorktree" },

This too looks like it should be in sort order. If so you are inserting at the wrong place.

Show 12 quoted lines
>  	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge" },
>  	[ADVICE_DEFAULT_BRANCH_NAME]			= { "defaultBranchName" },
>  	[ADVICE_DETACHED_HEAD]				= { "detachedHead" },
> diff --git a/advice.h b/advice.h
> index 727dcecf4a..6b11df945b 100644
> --- a/advice.h
> +++ b/advice.h
> @@ -16,6 +16,7 @@ enum advice_type {
>  	ADVICE_ADD_IGNORED_FILE,
>  	ADVICE_AMBIGUOUS_FETCH_REFSPEC,
>  	ADVICE_AM_WORK_DIR,
> +	ADVICE_BRANCH_USED_IN_OTHER_WORKTREE,
Correct sort order (if there is one).
Show 32 quoted lines
>  	ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
>  	ADVICE_COMMIT_BEFORE_MERGE,
>  	ADVICE_DEFAULT_BRANCH_NAME,
> diff --git a/branch.c b/branch.c
> index 26be358347..76aa2cbf44 100644
> --- a/branch.c
> +++ b/branch.c
> @@ -844,7 +844,7 @@ void remove_branch_state(struct repository *r, int
> verbose)
>  	remove_merge_branch_state(r);
>  }
>[snip diff]
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index f9453473fe..e4b78f4a05 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -1582,8 +1582,16 @@ static void
> die_if_switching_to_a_branch_in_use(struct checkout_opts *opts,
>  		return;
>  	head_ref = refs_resolve_refdup(get_main_ref_store(the_repository),
>  				       "HEAD", 0, NULL, &flags);
> -	if (head_ref && (!(flags & REF_ISSYMREF) || strcmp(head_ref,
> full_ref)))
> -		die_if_checked_out(full_ref, 1);
> +	if (head_ref && (!(flags & REF_ISSYMREF) || strcmp(head_ref,
> full_ref))) {
> +		int code = die_message_if_checked_out(full_ref, 1);
> +		if (code) {
> +			advise_if_enabled(
> +				ADVICE_BRANCH_USED_IN_OTHER_WORKTREE,
> +				_("Use --detach to avoid this restriction,\n"
> +				"or --ignore-other-worktrees to ignore it."));

I don’t know if `--detach` will “avoid” the restriction. (In fact `--ignore-other-worktrees` might be the one that *avoids* it (turns it off)?)

Technically the only point of being-on-a-branch is to be able to advance it. You know that. But does the advice-receiver? Because they might use the hint to get what they want immediately. Then later wonder why all the work they did on the branch “had no effect”.

Show 8 quoted lines
> +			exit(code);
> +		}
> +	}
>  	free(head_ref);
>  }
>
> --
> 2.51.0
No updates to tests were covered in another email.
-- 
Kristoffer Haugsbakk
Previous: Gabriel SchererNext: Gabriel Scherer
Message 3 of 20 in “extend --ignore-other-worktrees to 'rebase', add hints”
  1. 0/3 extend --ignore-other-worktrees to 'rebase', add hintsGabriel Scherer, Sep 13, 2025
  2. 1/3 checkout: provide hint when failing due to another worktreeGabriel Scherer, Sep 13, 2025
  3. Kristoffer HaugsbakkSep 13, 2025
  4. Gabriel SchererSep 14, 2025
  5. Junio C HamanoSep 15, 2025
  6. Gabriel SchererSep 15, 2025
  7. Junio C HamanoSep 16, 2025
  8. Junio C HamanoSep 17, 2025
  9. Gabriel SchererSep 17, 2025
  10. Phillip WoodSep 19, 2025
  11. Ben KnobleSep 14, 2025
  12. Ben KnobleSep 14, 2025
  13. Kristoffer HaugsbakkSep 14, 2025
  14. 2/3 rebase: support --ignore-other-worktreesGabriel Scherer, Sep 13, 2025
  15. Phillip WoodSep 15, 2025
  16. Junio C HamanoSep 15, 2025
  17. 3/3 rebase: hint when failing on branch used by another worktreeGabriel Scherer, Sep 13, 2025
  18. Ben KnobleSep 13, 2025
  19. Gabriel SchererSep 13, 2025
  20. Phillip WoodSep 15, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.