checkout: forbid "-B <branch>" from touching a branch used elsewhere

"git checkout -B <branch> [<start-point>]", being a "forced" version
of "-b", switches to the <branch>, after optionally resetting its
tip to the <start-point>, even if the <branch> is in use in another
worktree, which is somewhat unexpected.

Protect the <branch> using the same logic that forbids "git checkout
<branch>" from touching a branch that is in use elsewhere.

This is a breaking change that may deserve backward compatibliity
warning in the Release Notes.  The "--ignore-other-worktrees" option
can be used as an escape hatch if the finger memory of existing
users depend on the current behaviour of "-B".

Reported-by: Willem Verstraeten <willem.verstraeten@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano
2023-11-23 15:00:31 +09:00
parent 9263c40a0a
commit b23285a921
5 changed files with 41 additions and 3 deletions

View File

@ -1600,6 +1600,13 @@ static int checkout_branch(struct checkout_opts *opts,
if (new_branch_info->path && !opts->force_detach && !opts->new_branch)
die_if_switching_to_a_branch_in_use(opts, new_branch_info->path);
/* "git checkout -B <branch>" */
if (opts->new_branch_force) {
char *full_ref = xstrfmt("refs/heads/%s", opts->new_branch);
die_if_switching_to_a_branch_in_use(opts, full_ref);
free(full_ref);
}
if (!new_branch_info->commit && opts->new_branch) {
struct object_id rev;
int flag;