checkout: improve die_if_checked_out() robustness
[gitweb.git] / builtin / checkout.c
index 57545543ebcc46ef28ca4a22d399b5476de7af0b..1992c41d484e0755858bbe0be80618f3322b8349 100644 (file)
@@ -880,6 +880,11 @@ static void check_linked_checkout(struct branch_info *new, const char *id)
        struct strbuf gitdir = STRBUF_INIT;
        const char *start, *end;
 
+       /*
+        * $GIT_COMMON_DIR/HEAD is practically outside
+        * $GIT_DIR so resolve_ref_unsafe() won't work (it
+        * uses git_path). Parse the ref ourselves.
+        */
        if (id)
                strbuf_addf(&path, "%s/worktrees/%s/HEAD", get_git_common_dir(), id);
        else
@@ -910,25 +915,20 @@ static void check_linked_checkout(struct branch_info *new, const char *id)
        strbuf_release(&gitdir);
 }
 
-static void check_linked_checkouts(struct branch_info *new)
+static void die_if_checked_out(struct branch_info *new)
 {
        struct strbuf path = STRBUF_INIT;
        DIR *dir;
        struct dirent *d;
 
+       check_linked_checkout(new, NULL);
+
        strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
        if ((dir = opendir(path.buf)) == NULL) {
                strbuf_release(&path);
                return;
        }
 
-       /*
-        * $GIT_COMMON_DIR/HEAD is practically outside
-        * $GIT_DIR so resolve_ref_unsafe() won't work (it
-        * uses git_path). Parse the ref ourselves.
-        */
-       check_linked_checkout(new, NULL);
-
        while ((d = readdir(dir)) != NULL) {
                if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
                        continue;
@@ -1145,14 +1145,14 @@ static int checkout_branch(struct checkout_opts *opts,
                die(_("Cannot switch branch to a non-commit '%s'"),
                    new->name);
 
-       if (new->path && !opts->force_detach && !opts->new_branch) {
+       if (new->path && !opts->force_detach && !opts->new_branch &&
+           !opts->ignore_other_worktrees) {
                unsigned char sha1[20];
                int flag;
                char *head_ref = resolve_refdup("HEAD", 0, sha1, &flag);
                if (head_ref &&
-                   (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)) &&
-                   !opts->ignore_other_worktrees)
-                       check_linked_checkouts(new);
+                   (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)))
+                       die_if_checked_out(new);
                free(head_ref);
        }