checkout: teach check_linked_checkout() about symbolic link HEAD

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>

Eric Sunshine committed Jul 17, 2015 at 19:00 UTC 746bbdc64f1e1b2618cd71e5da81e38aa772e8ba
2 files changed +13 -1
builtin/checkout.c
+5 -1
@@ -889,7 +889,11 @@ static void check_linked_checkout(const char *branch, const char *id)
889 else
890 strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
891
892 - if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
892 + if (!strbuf_readlink(&sb, path.buf, 0)) {
893 + if (!starts_with(sb.buf, "refs/") ||
894 + check_refname_format(sb.buf, 0))
895 + goto done;
896 + } else if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
897 starts_with(sb.buf, "ref:")) {
898 strbuf_remove(&sb, 0, strlen("ref:"));
899 strbuf_trim(&sb);
t/t2025-worktree-add.sh
+8
@@ -83,6 +83,14 @@ test_expect_success 'die the same branch is already checked out' '
83 )
84 '
85
86 +test_expect_success SYMLINKS 'die the same branch is already checked out (symlink)' '
87 + head=$(git -C there rev-parse --git-path HEAD) &&
88 + ref=$(git -C there symbolic-ref HEAD) &&
89 + rm "$head" &&
90 + ln -s "$ref" "$head" &&
91 + test_must_fail git -C here checkout newmaster
92 +'
93 +
94 test_expect_success 'not die the same branch is already checked out' '
95 (
96 cd here &&