Skip to content

Commit

Permalink
worktree: detect branch-name/detached and error conditions locally
Browse files Browse the repository at this point in the history
git-worktree currently conflates setting of HEAD in the new worktree
with initial worktree population via a single git-checkout invocation,
which requires git-checkout to have special knowledge that it is
operating in a newly created worktree. The eventual goal is to separate
these operations and rid git-checkout of that overly-intimate knowledge.

Once these operations are separate, git-worktree will no longer be able
to rely upon git-branch to determine the state of the worktree (branch
name or detached), 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 name or detached state locally, and to perform error checking on
its own.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Eric Sunshine authored and Junio C Hamano committed Jul 20, 2015
1 parent 80a0548 commit f7c9dac
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions builtin/worktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -188,11 +190,26 @@ static int add_worktree(const char *path, const char *refname,
struct child_process cp;
struct argv_array child_env = ARGV_ARRAY_INIT;
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);

/* is 'refname' a branch or commit? */
if (opts->force_new_branch) /* definitely a branch */
;
else if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&
ref_exists(symref.buf)) { /* it's a branch */
if (!opts->force)
die_if_checked_out(symref.buf);
} else { /* must be a commit */
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));
Expand Down Expand Up @@ -281,6 +298,7 @@ static int add_worktree(const char *path, const char *refname,
unlink_or_warn(sb.buf);
argv_array_clear(&child_env);
strbuf_release(&sb);
strbuf_release(&symref);
strbuf_release(&sb_repo);
strbuf_release(&sb_git);
return ret;
Expand Down

0 comments on commit f7c9dac

Please sign in to comment.