The eventual goal is for git-worktree to populate the new worktree via
"git reset --hard" rather than "git checkout". As a consequence,
git-worktree will no longer be able to rely upon git-branch to determine
the state of the worktree (detached or branch symref), or to check for
error conditions, such as the requested branch already checked out
elsewhere, or an invalid reference. Therefore, imbue git-worktree with
the intelligence to determine a branch symref or detached state locally,
and to perform error checking on its own.

Signed-off-by: Eric Sunshine <sunsh...@sunshineco.com>
---

This patch is somewhat RFC since I spent a lot of time browsing the
branch- and ref-related APIs figuring out how to determine if the
provided refname was a branch name or some other (detached) reference.
I'm not at all sure that my use of strbuf_check_branch_ref(),
ref_exists(), and lookup_commit_reference_by_name() is the best
approach, or even appropriate, although it seems to work as desired.

 builtin/worktree.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index e04a6d1..babdef1 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -3,6 +3,8 @@
 #include "dir.h"
 #include "parse-options.h"
 #include "argv-array.h"
+#include "branch.h"
+#include "refs.h"
 #include "run-command.h"
 #include "sigchain.h"
 
@@ -187,11 +189,23 @@ static int add_worktree(const char *path, const char 
*refname,
        struct stat st;
        struct child_process cp;
        int counter = 0, len, ret;
+       struct strbuf symref = STRBUF_INIT;
+       struct commit *commit = NULL;
        unsigned char rev[20];
 
        if (file_exists(path) && !is_empty_dir(path))
                die(_("'%s' already exists"), path);
 
+       if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&
+           ref_exists(symref.buf)) {
+               if (!opts->force)
+                       die_if_checked_out(symref.buf);
+       } else {
+               commit = lookup_commit_reference_by_name(refname);
+               if (!commit)
+                       die(_("invalid reference: %s"), refname);
+       }
+
        name = worktree_basename(path, &len);
        strbuf_addstr(&sb_repo,
                      git_path("worktrees/%.*s", (int)(path + len - name), 
name));
@@ -278,6 +292,7 @@ static int add_worktree(const char *path, const char 
*refname,
        strbuf_addf(&sb, "%s/locked", sb_repo.buf);
        unlink_or_warn(sb.buf);
        strbuf_release(&sb);
+       strbuf_release(&symref);
        strbuf_release(&sb_repo);
        strbuf_release(&sb_git);
        return ret;
-- 
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