checkout: refactor die_if_checked_out() caller

There is a bit dense logic to make a call to "die_if_checked_out()" while trying to check out a branch. Extract it into a helper function and give it a bit of comment to describe what is going on. The most important part of the refactoring is the separation of the guarding logic before making the call to die_if_checked_out() into the caller specific part (e.g., the logic that decides that the caller is trying to check out an existing branch) and the bypass due to the "--ignore-other-worktrees" option. The latter will be common no matter how the current or future callers decides they need this protection. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Nov 23, 2023 at 14:11 UTC 9263c40a0a0c299db59b8a64e87b95026a28812a
1 file changed +23 -9
builtin/checkout.c
+23 -9
@@ -1516,6 +1516,26 @@ static void die_if_some_operation_in_progress(void)
1516 wt_status_state_free_buffers(&state);
1517 }
1518
1519 +/*
1520 + * die if attempting to checkout an existing branch that is in use
1521 + * in another worktree, unless ignore-other-wortrees option is given.
1522 + * The check is bypassed when the branch is already the current one,
1523 + * as it will not make things any worse.
1524 + */
1525 +static void die_if_switching_to_a_branch_in_use(struct checkout_opts *opts,
1526 + const char *full_ref)
1527 +{
1528 + int flags;
1529 + char *head_ref;
1530 +
1531 + if (opts->ignore_other_worktrees)
1532 + return;
1533 + head_ref = resolve_refdup("HEAD", 0, NULL, &flags);
1534 + if (head_ref && (!(flags & REF_ISSYMREF) || strcmp(head_ref, full_ref)))
1535 + die_if_checked_out(full_ref, 1);
1536 + free(head_ref);
1537 +}
1538 +
1539 static int checkout_branch(struct checkout_opts *opts,
1540 struct branch_info *new_branch_info)
1541 {
@@ -1576,15 +1596,9 @@ static int checkout_branch(struct checkout_opts *opts,
1596 if (!opts->can_switch_when_in_progress)
1597 die_if_some_operation_in_progress();
1598
1579 - if (new_branch_info->path && !opts->force_detach && !opts->new_branch &&
1580 - !opts->ignore_other_worktrees) {
1581 - int flag;
1582 - char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag);
1583 - if (head_ref &&
1584 - (!(flag & REF_ISSYMREF) || strcmp(head_ref, new_branch_info->path)))
1585 - die_if_checked_out(new_branch_info->path, 1);
1586 - free(head_ref);
1587 - }
1599 + /* "git checkout <branch>" */
1600 + if (new_branch_info->path && !opts->force_detach && !opts->new_branch)
1601 + die_if_switching_to_a_branch_in_use(opts, new_branch_info->path);
1602
1603 if (!new_branch_info->commit && opts->new_branch) {
1604 struct object_id rev;