worktree add -B: do the checkout test before update branch
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Mon, 15 Feb 2016 13:35:33 +0000 (20:35 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Feb 2016 23:54:13 +0000 (15:54 -0800)
If --force is not given but -B is, we should not proceed if the given
branch is already checked out elsewhere. add_worktree() has this test,
but it kicks in too late when "git branch --force" is already
executed. As a result, even though we correctly refuse to create a new
worktree, we have already updated the branch and mess up the other
checkout.

Repeat the die_if_checked_out() test again for this specific case before
"git branch" runs.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/worktree.c
t/t2025-worktree-add.sh
index 6b9c946693ff5e0127dd4a6d0f6c93ba84631edb..20cf67a549b0d293f42e7f7c21f8822d06aa9c7c 100644 (file)
@@ -334,9 +334,18 @@ static int add(int ac, const char **av, const char *prefix)
        branch = ac < 2 ? "HEAD" : av[1];
 
        opts.force_new_branch = !!new_branch_force;
-       if (opts.force_new_branch)
+       if (opts.force_new_branch) {
+               struct strbuf symref = STRBUF_INIT;
+
                opts.new_branch = new_branch_force;
 
+               if (!opts.force &&
+                   !strbuf_check_branch_ref(&symref, opts.new_branch) &&
+                   ref_exists(symref.buf))
+                       die_if_checked_out(symref.buf);
+               strbuf_release(&symref);
+       }
+
        if (ac < 2 && !opts.new_branch && !opts.detach) {
                int n;
                const char *s = worktree_basename(path, &n);
index a4d36c0892db686a7677cf1ab23a9f8ed81859eb..cbfa41ec61b9f893b4df441e0289a5313ccaf413 100755 (executable)
@@ -193,6 +193,13 @@ test_expect_success '"add" -B/--detach mutually exclusive' '
        test_must_fail git worktree add -B poodle --detach bamboo master
 '
 
+test_expect_success '"add -B" fails if the branch is checked out' '
+       git rev-parse newmaster >before &&
+       test_must_fail git worktree add -B newmaster bamboo master &&
+       git rev-parse newmaster >after &&
+       test_cmp before after
+'
+
 test_expect_success 'add -B' '
        git worktree add -B poodle bamboo2 master^ &&
        git -C bamboo2 symbolic-ref HEAD >actual &&