]> git.ipfire.org Git - thirdparty/git.git/commitdiff
branch: fix die_if_checked_out() when ignore_current_worktree
authorRubén Justo <rjusto@gmail.com>
Sat, 25 Feb 2023 14:22:02 +0000 (15:22 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 25 Feb 2023 21:05:23 +0000 (13:05 -0800)
In 8d9fdd7 (worktree.c: check whether branch is rebased in another
worktree, 2016-04-22) die_if_checked_out() learned a new option
ignore_current_worktree, to modify the operation from "die() if the
branch is checked out in any worktree" to "die() if the branch is
checked out in any worktree other than the current one".

Unfortunately we implemented it by checking the flag is_current in the
worktree that find_shared_symref() returns.

When the same branch is checked out in several worktrees simultaneously,
find_shared_symref() will return the first matching worktree in the list
composed by get_worktrees().  If one of the worktrees with the checked
out branch is the current worktree, find_shared_symref() may or may not
return it, depending on the order in the list.

Instead of find_shared_symref(), let's do the search using use the
recently introduced API is_shared_symref(), and consider
ignore_current_worktree when necessary.

Signed-off-by: Rubén Justo <rjusto@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
worktree.c

index d182756827fe5128292798b707a52aed25e7aa48..e04710b2b50e04ddc1c0015dddb34554ba2a1805 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -820,12 +820,16 @@ void remove_branch_state(struct repository *r, int verbose)
 void die_if_checked_out(const char *branch, int ignore_current_worktree)
 {
        struct worktree **worktrees = get_worktrees();
-       const struct worktree *wt;
 
-       wt = find_shared_symref(worktrees, "HEAD", branch);
-       if (wt && (!ignore_current_worktree || !wt->is_current)) {
-               skip_prefix(branch, "refs/heads/", &branch);
-               die(_("'%s' is already checked out at '%s'"), branch, wt->path);
+       for (int i = 0; worktrees[i]; i++) {
+               if (worktrees[i]->is_current && ignore_current_worktree)
+                       continue;
+
+               if (is_shared_symref(worktrees[i], "HEAD", branch)) {
+                       skip_prefix(branch, "refs/heads/", &branch);
+                       die(_("'%s' is already checked out at '%s'"),
+                               branch, worktrees[i]->path);
+               }
        }
 
        free_worktrees(worktrees);
index 40cb9874b74f237c7ddfbb1ecdf9cfc15bbe65bd..34043d8fe04cb2fd0ac2b40ccff330e17b0e0811 100644 (file)
@@ -435,10 +435,9 @@ const struct worktree *find_shared_symref(struct worktree **worktrees,
                                          const char *target)
 {
 
-       for (int i = 0; worktrees[i]; i++) {
+       for (int i = 0; worktrees[i]; i++)
                if (is_shared_symref(worktrees[i], symref, target))
                        return worktrees[i];
-       }
 
        return NULL;
 }