Subject: Re: git worktree fails to recreate existing branch even with -B

From: Duy Nguyen <[email-masked]>
Date: Mon, 15 Feb 2016 16:41:54 +0700

On Tue, Feb 09, 2016 at 05:54:01PM +0300, Kirill Likhodedov wrote:
> Git doesn’t allow me to execute 
>     git worktree add -B <branch> <path> <start-point>
> where <branch> already exists in the repository.
> 
> The command prints the following:
>     Preparing <path> (identifier <branch>)
>     fatal: Refusing to point HEAD outside of refs/
> 
> I’m trying to create a worktree on an existing branch <branch>,
> which should point to <start-point>. This obviously should fail with
> “-b”, but I use “-B” and expect it to be reset to <start-point> as
> mentioned in the docs:
> 
>     By default, -b refuses to create a new branch if it already exists.  
>     -B overrides this safeguard, resetting <new-branch> to <branch>.
> 
> Do I miss something or there is a bug?

According to the man page, this looks like a bug.

> Steps to reproduce:
> 
> git init wt
> cd wt
> echo 'asd' > a.txt ; git add a.txt ; git commit -m initial
> git branch br1
> git worktree add -B br1 ~/temp/br1 master
> 
> Error message:
> Preparing /Users/loki/temp/br1 (identifier br1)
> fatal: Refusing to point HEAD outside of refs/

GIT_TRACE=2 gives me

trace: built-in: git 'symbolic-ref' 'HEAD' ''
fatal: Refusing to point HEAD outside of refs/

So we pass wrong argument to symbolic-ref. The '' should be
'refs/heads/br1'. This patch seems to fix it.

-- 8< --
diff --git a/builtin/worktree.c b/builtin/worktree.c
index 475b958..d5b319f 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -202,7 +202,7 @@ static int add_worktree(const char *path, const char *refname,
 
 	/* is 'refname' a branch or commit? */
 	if (opts->force_new_branch) /* definitely a branch */
-		;
+		strbuf_addf(&symref, "refs/heads/%s", refname);
 	else if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&
 		 ref_exists(symref.buf)) { /* it's a branch */
 		if (!opts->force)
-- 8< --
--
Duy