checkout: teach check_linked_checkout() about symbolic link HEAD
authorEric Sunshine <sunshine@sunshineco.com>
Fri, 17 Jul 2015 23:00:03 +0000 (19:00 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Jul 2015 18:29:24 +0000 (11:29 -0700)
check_linked_checkout() only understands symref-style HEAD (i.e. "ref:
refs/heads/master"), however, HEAD may also be a an actual symbolic link
(on platforms which support it). To accurately detect if a branch is
checked out elsewhere, it needs to handle symbolic link HEAD, as well.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/checkout.c
t/t2025-worktree-add.sh
index 6f4e49232adc5d89850d6211b7cdf3c926821e7a..f04dcaaf1f714504a37181658d70351b1110c002 100644 (file)
@@ -889,7 +889,11 @@ static void check_linked_checkout(const char *branch, const char *id)
        else
                strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
 
-       if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
+       if (!strbuf_readlink(&sb, path.buf, 0)) {
+               if (!starts_with(sb.buf, "refs/") ||
+                   check_refname_format(sb.buf, 0))
+                       goto done;
+       } else if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
            starts_with(sb.buf, "ref:")) {
                strbuf_remove(&sb, 0, strlen("ref:"));
                strbuf_trim(&sb);
index ead8aa2a9d78c8f6451d19812d48ae5d69e6ee69..9e30690692d35f25ebbbe6670a19f1effd9b688e 100755 (executable)
@@ -83,6 +83,14 @@ test_expect_success 'die the same branch is already checked out' '
        )
 '
 
+test_expect_success SYMLINKS 'die the same branch is already checked out (symlink)' '
+       head=$(git -C there rev-parse --git-path HEAD) &&
+       ref=$(git -C there symbolic-ref HEAD) &&
+       rm "$head" &&
+       ln -s "$ref" "$head" &&
+       test_must_fail git -C here checkout newmaster
+'
+
 test_expect_success 'not die the same branch is already checked out' '
        (
                cd here &&