git-worktree will eventually be retrofitted to populate the new worktree
via "git reset --hard" rather than "git checkout", at which time it will
need to be able to detect if the branch is already checked out
elsewhere, rather than relying upon git-branch to make this
determination, so publish die_if_checked_out().

Signed-off-by: Eric Sunshine <sunsh...@sunshineco.com>
---
 branch.c           | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 branch.h           |  7 ++++++
 builtin/checkout.c | 65 ------------------------------------------------------
 3 files changed, 72 insertions(+), 65 deletions(-)

diff --git a/branch.c b/branch.c
index 4bab55a..7b8b9a3 100644
--- a/branch.c
+++ b/branch.c
@@ -309,3 +309,68 @@ void remove_branch_state(void)
        unlink(git_path("MERGE_MODE"));
        unlink(git_path("SQUASH_MSG"));
 }
+
+static void check_linked_checkout(const char *branch, const char *id)
+{
+       struct strbuf sb = STRBUF_INIT;
+       struct strbuf path = STRBUF_INIT;
+       struct strbuf gitdir = STRBUF_INIT;
+       const char *start, *end;
+
+       if (id)
+               strbuf_addf(&path, "%s/worktrees/%s/HEAD", 
get_git_common_dir(), id);
+       else
+               strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
+
+       if (strbuf_read_file(&sb, path.buf, 0) < 0 ||
+           !skip_prefix(sb.buf, "ref:", &start))
+               goto done;
+       while (isspace(*start))
+               start++;
+       end = start;
+       while (*end && !isspace(*end))
+               end++;
+       if (strncmp(start, branch, end - start) || branch[end - start] != '\0')
+               goto done;
+       if (id) {
+               strbuf_reset(&path);
+               strbuf_addf(&path, "%s/worktrees/%s/gitdir", 
get_git_common_dir(), id);
+               if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
+                       goto done;
+               strbuf_rtrim(&gitdir);
+       } else
+               strbuf_addstr(&gitdir, get_git_common_dir());
+       skip_prefix(branch, "refs/heads/", &branch);
+       die(_("'%s' is already checked out at '%s'"), branch, gitdir.buf);
+done:
+       strbuf_release(&path);
+       strbuf_release(&sb);
+       strbuf_release(&gitdir);
+}
+
+void die_if_checked_out(const char *branch)
+{
+       struct strbuf path = STRBUF_INIT;
+       DIR *dir;
+       struct dirent *d;
+
+       /*
+        * $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(branch, NULL);
+
+       strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
+       dir = opendir(path.buf);
+       strbuf_release(&path);
+       if (!dir)
+               return;
+
+       while ((d = readdir(dir)) != NULL) {
+               if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+                       continue;
+               check_linked_checkout(branch, d->d_name);
+       }
+       closedir(dir);
+}
diff --git a/branch.h b/branch.h
index 64173ab..58aa45f 100644
--- a/branch.h
+++ b/branch.h
@@ -52,4 +52,11 @@ extern void install_branch_config(int flag, const char 
*local, const char *origi
  */
 extern int read_branch_desc(struct strbuf *, const char *branch_name);
 
+/*
+ * Check if a branch is checked out in the main worktree or any linked
+ * worktree and die (with a message describing its checkout location) if
+ * it is.
+ */
+extern void die_if_checked_out(const char *branch);
+
 #endif
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 673daa0..4ae895c 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -873,71 +873,6 @@ static const char *unique_tracking_name(const char *name, 
unsigned char *sha1)
        return NULL;
 }
 
-static void check_linked_checkout(const char *branch, const char *id)
-{
-       struct strbuf sb = STRBUF_INIT;
-       struct strbuf path = STRBUF_INIT;
-       struct strbuf gitdir = STRBUF_INIT;
-       const char *start, *end;
-
-       if (id)
-               strbuf_addf(&path, "%s/worktrees/%s/HEAD", 
get_git_common_dir(), id);
-       else
-               strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
-
-       if (strbuf_read_file(&sb, path.buf, 0) < 0 ||
-           !skip_prefix(sb.buf, "ref:", &start))
-               goto done;
-       while (isspace(*start))
-               start++;
-       end = start;
-       while (*end && !isspace(*end))
-               end++;
-       if (strncmp(start, branch, end - start) || branch[end - start] != '\0')
-               goto done;
-       if (id) {
-               strbuf_reset(&path);
-               strbuf_addf(&path, "%s/worktrees/%s/gitdir", 
get_git_common_dir(), id);
-               if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
-                       goto done;
-               strbuf_rtrim(&gitdir);
-       } else
-               strbuf_addstr(&gitdir, get_git_common_dir());
-       skip_prefix(branch, "refs/heads/", &branch);
-       die(_("'%s' is already checked out at '%s'"), branch, gitdir.buf);
-done:
-       strbuf_release(&path);
-       strbuf_release(&sb);
-       strbuf_release(&gitdir);
-}
-
-static void die_if_checked_out(const char *branch)
-{
-       struct strbuf path = STRBUF_INIT;
-       DIR *dir;
-       struct dirent *d;
-
-       /*
-        * $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(branch, NULL);
-
-       strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
-       dir = opendir(path.buf);
-       strbuf_release(&path);
-       if (!dir)
-               return;
-
-       while ((d = readdir(dir)) != NULL) {
-               if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
-                       continue;
-               check_linked_checkout(branch, d->d_name);
-       }
-       closedir(dir);
-}
-
 static int parse_branchname_arg(int argc, const char **argv,
                                int dwim_new_local_branch_ok,
                                struct branch_info *new,
-- 
2.5.0.rc1.201.ga12d9f8

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to