summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-03-02 03:23:18 -0500
committerJunio C Hamano <gitster@pobox.com>2017-03-02 11:05:04 -0800
commitfd4692ff7040e690546ed139a419995e76a96196 (patch)
tree22b7d5f9415dd2a1d74f885d95af2e29608f9a88 /t
parent7d5c960bf6f98601dce992f1ffaf4c7ab932e6dc (diff)
downloadgit-fd4692ff7040e690546ed139a419995e76a96196.tar.gz
checkout: restrict @-expansions when finding branchjk/interpret-branch-name
When we parse "git checkout $NAME", we try to interpret $NAME as a local branch-name. If it is, then we point HEAD to that branch. Otherwise, we detach the HEAD at whatever commit $NAME points to. We do the interpretation by calling strbuf_branchname(), and then blindly sticking "refs/heads/" on the front. This leads to nonsense results when expansions like "@{upstream}" or "@" point to something besides a local branch. We end up with a local branch name like "refs/heads/origin/master" or "refs/heads/HEAD". Normally this has no user-visible effect because those branches don't exist, and so we fallback to feeding the result to get_sha1(), which resolves them correctly. But as the new test in t3204 shows, there are corner cases where the effect is observable, and we check out the wrong local branch rather than detaching to the correct one. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't')
-rwxr-xr-xt/t3204-branch-name-interpretation.sh10
1 files changed, 10 insertions, 0 deletions
diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh
index 05e88f92d9..698d9cc4f3 100755
--- a/t/t3204-branch-name-interpretation.sh
+++ b/t/t3204-branch-name-interpretation.sh
@@ -120,4 +120,14 @@ test_expect_success 'delete branch named "@"' '
expect_deleted refs/heads/@
'
+test_expect_success 'checkout does not treat remote @{upstream} as a branch' '
+ git update-ref refs/remotes/origin/checkout one &&
+ git branch --set-upstream-to=origin/checkout &&
+ git update-ref refs/heads/origin/checkout two &&
+ git update-ref refs/heads/remotes/origin/checkout two &&
+
+ git checkout @{upstream} &&
+ expect_branch HEAD one
+'
+
test_done