worktree: make setup of new HEAD distinct from worktree population
authorEric Sunshine <sunshine@sunshineco.com>
Fri, 17 Jul 2015 23:00:14 +0000 (19:00 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Jul 2015 18:29:52 +0000 (11:29 -0700)
git-worktree currently conflates setting of HEAD in the new worktree and
initial worktree population into a single git-checkout invocation which
requires git-checkout to have special knowledge that it is operating on
a newly created worktree. The eventual goal is to rid git-checkout of
that overly-intimate knowledge.

Once these operations are separate, git-worktree will no longer be able
to delegate to git-branch the setting of the new worktree's HEAD to the
desired branch (or commit, if detached). Therefore, make git-worktree
itself responsible for setting up HEAD as either a symbolic reference,
if associated with a branch, or detached, if not.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/worktree.c
index cf35b2aa7e2b7d495dbed61a9581fbb7dac45c8d..79d088c4a891066b65dc2edb0de2a46ae2d5c8b0 100644 (file)
@@ -278,12 +278,21 @@ static int add_worktree(const char *path, const char *refname,
        argv_array_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
        memset(&cp, 0, sizeof(cp));
        cp.git_cmd = 1;
+
+       if (commit)
+               argv_array_pushl(&cp.args, "update-ref", "HEAD",
+                                sha1_to_hex(commit->object.sha1), NULL);
+       else
+               argv_array_pushl(&cp.args, "symbolic-ref", "HEAD",
+                                symref.buf, NULL);
+       cp.env = child_env.argv;
+       ret = run_command(&cp);
+       if (ret)
+               goto done;
+
+       cp.argv = NULL;
+       argv_array_clear(&cp.args);
        argv_array_push(&cp.args, "checkout");
-       if (opts->force)
-               argv_array_push(&cp.args, "--ignore-other-worktrees");
-       if (opts->detach)
-               argv_array_push(&cp.args, "--detach");
-       argv_array_push(&cp.args, refname);
        cp.env = child_env.argv;
        ret = run_command(&cp);
        if (!ret) {
@@ -293,6 +302,7 @@ static int add_worktree(const char *path, const char *refname,
                junk_work_tree = NULL;
                junk_git_dir = NULL;
        }
+done:
        strbuf_reset(&sb);
        strbuf_addf(&sb, "%s/locked", sb_repo.buf);
        unlink_or_warn(sb.buf);