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

Re: git checkout -B <branch> lets you checkout a branch that is already checked out in another worktree Inbox

From
WVWillem Verstraeten <willem.verstraeten@gmail.com>
Date
Nov 23, 2023, 12:12 UTC
Message-ID
<CAGX9RpHOOu71LJa_Z_29b6hwy7s_+oxGv0U1kdt+CJ_Ztg1iSw@mail.gmail.com>
In-Reply-To
<xmqqjzq9cl70.fsf@gitster.g>
Show 8 quoted lines
> >     git checkout -f main origin/main #also reports a fatal error, as expected
>
> This is expected because origin/main is taken as pathspec, and it is
> a request to checkout the paths that match the pathspec out of the
> named tree-ish (i.e., "main"), even when these paths have local
> changes, but you do not have paths that match "origin/main".  The
> failure is not because "main" is checked out elsewhere.
>

My mistake: I meant to do `git branch -f main origin/main`, as documented for `git checkout -B main origin/main`

So, for completeness' sake, this is my revised reproduction scenario that actually demonstrates the problem I have:

    ~/temp> git clone https://github.com/servo/pathfinder.git primary
    Cloning into 'primary'...
    ....
    ~/temp> cd primary
    ~/temp/primary> git worktree add -b metal ../secondary origin/metal
    Preparing worktree (new branch 'metal')
    branch 'metal' set up to track 'origin/metal'.
    HEAD is now at 1cdcc209 wip
    ~/temp/primary> cd ..\secondary\
    ~/temp/secondary> git checkout main
    fatal: 'main' is already used by worktree at ../primary'
    ~/temp/secondary> git branch -f main origin/main
    fatal: cannot force update the branch 'main' used by worktree at
'../primary'
    ~/temp/secondary> git checkout -B main origin/main
    Switched to and reset branch 'main'
    branch 'main' set up to track 'origin/main'.
    Your branch is up to date with 'origin/main'.

I would expect that last `git checkout -B ...` to fail with a similar error as the `git branch -f ...` command right before that, since the documentation for `git checkout -B <branch> <start-point>` states that it is the atomic equivalent of `git branch -f <branch> <start-point> ; git checkout <branch>`

Show 8 quoted lines
> I guess we could change the behaviour so that
>
>     git checkout -B <branch> [<start-point>]
>
> fails when <branch> is an existing branch that is in use in another
> worktree, and allow "-f" to be used to override the safety, i.e.,
>
>     git checkout -f -B <branch> [<start-point>]
I would be very much in favor of that, indeed.

However, as you noted in your follow-up mail, the --ignore-other-worktrees option would be better suited than the -f flag.

> It turns out that for some reason "-f" is not how we decided to
> override this one---there is "--ignore-other-worktrees" option.
This means it would look like this then, if you decide to tackle this?
    ~/temp/secondary> git checkout -B metal origin/metal
    fatal: cannot force update the branch 'main' used by worktree at
'../primary'
    ~/temp/secondary> git checkout --ignore-other-worktrees -B metal
origin/metal
    Switched to and reset branch 'metal'
    branch 'metal' set up to track 'origin/metal'.
    Your branch is up to date with 'origin/metal'.

My thoughts as an experienced user, though not an experienced contributor, admittedly :)

Kind regards, Willem Verstraeten

On Thu, 23 Nov 2023 at 02:28, Junio C Hamano <gitster@pobox.com> wrote:
Show 62 quoted lines
>
> Willem Verstraeten <willem.verstraeten@gmail.com> writes:
>
> >     git checkout -b main #reports a fatal error, as expected
>
> This is expected because "main" already exists, not because "main"
> is checked out elsewhere.
>
> >     git checkout -f main origin/main #also reports a fatal error, as expected
>
> This is expected because origin/main is taken as pathspec, and it is
> a request to checkout the paths that match the pathspec out of the
> named tree-ish (i.e., "main"), even when these paths have local
> changes, but you do not have paths that match "origin/main".  The
> failure is not because "main" is checked out elsewhere.
>
> A slight variant of the command
>
>     git checkout -f -b main origin/main
>
> still fails for the same reason as the first of your examples above.
>
> It is a tangent, but I suspect this failure may be a bit unexpected.
> In this example, "-f"orce could be overriding the usual failure from
> "-b" to switch to a branch that already exists, but that is what
> "-B" does, and "-f -b" does not work as a synonym for "-B".
>
> In any case, these example you marked "fail as expected" do fail as
> expected, but they fail for reasons that have nothing to do with the
> protection of branches that are used in other worktrees.
>
> >     git checkout -B main origin/main # ----> this succeeds, which is
> > unexpected <----
>
> I agree this may be undesirable.
>
> But it makes sort of sense, because "-B" is a forced form of "-b"
> (i.e., it tells git: even when "-b" would fail, take necessary
> measures to make it work), and we can view that it is part of
> "forcing" to override the protection over branches that are used
> elsewhere.
>
> I guess we could change the behaviour so that
>
>     git checkout -B <branch> [<start-point>]
>
> fails when <branch> is an existing branch that is in use in another
> worktree, and allow "-f" to be used to override the safety, i.e.,
>
>     git checkout -f -B <branch> [<start-point>]
>
> would allow the <branch> to be repointed to <start-point> (or HEAD)
> even when it is used elsewhere.
>
> Thoughts, whether they agree or disagree with what I just said, by
> other experienced contributors are very much welcome, before I can
> say "patches welcome" ;-).
>
> Willem, thanks for raising the issue.
>
>
>
Previous: Andy Koppe
Message 17 of 17 in “git checkout -B <branch> lets you checkout a branch that is already checked out in another worktree Inbox”
  1. Willem VerstraetenNov 22, 2023
  2. Junio C HamanoNov 23, 2023
  3. Junio C HamanoNov 23, 2023
  4. 2/2 checkout: forbid "-B <branch>" from touching a branch used elsewhereJunio C Hamano, Nov 23, 2023
  5. Phillip WoodNov 23, 2023
  6. Eric SunshineNov 23, 2023
  7. Junio C HamanoNov 24, 2023
  8. Junio C HamanoNov 27, 2023
  9. Jeff KingNov 27, 2023
  10. Phillip WoodNov 30, 2023
  11. Willem VerstraetenDec 4, 2023
  12. Eric SunshineDec 4, 2023
  13. Junio C HamanoDec 8, 2023
  14. Willem VerstraetenJan 30, 2024
  15. Junio C HamanoJan 30, 2024
  16. Andy KoppeNov 23, 2023
  17. Willem VerstraetenNov 23, 2023

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.