diff options
author | Junio C Hamano <gitster@pobox.com> | 2007-06-08 01:19:13 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-06-08 01:19:13 -0700 |
commit | 5035242c4785bd23c53827a1656b5f97394f724e (patch) | |
tree | f7ea750c986e73b3d1eff27070e547f8d5373857 | |
parent | 23fcdc79713c47a6a0d50762b9311c9933a60d3f (diff) | |
download | git-5035242c4785bd23c53827a1656b5f97394f724e.tar.gz |
checkout: do not get confused with ambiguous tag/branch names
Although it is not advisable, we have always allowed a branch
and a tag to have the same basename (i.e. it is not illegal to
have refs/heads/frotz and refs/tags/frotz at the same time).
When talking about a specific commit, the interpretation of
'frotz' has always been "use tag and then check branch",
although we warn when ambiguities exist.
However "git checkout $name" is defined to (1) first see if it
matches the branch name, and if so switch to that branch; (2)
otherwise it is an instruction to detach HEAD to point at the
commit named by $name. We did not follow this definition when
$name appeared under both refs/heads/ and refs/tags/ -- we
switched to the branch but read the tree from the tagged commit,
which was utterly bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | git-checkout.sh | 3 | ||||
-rwxr-xr-x | t/t7201-co.sh | 40 |
2 files changed, 42 insertions, 1 deletions
diff --git a/git-checkout.sh b/git-checkout.sh index ed7c2c5f6a..7c5ca3d62f 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -63,12 +63,13 @@ while [ "$#" != "0" ]; do echo "unknown flag $arg" exit 1 fi - new="$rev" new_name="$arg" if git-show-ref --verify --quiet -- "refs/heads/$arg" then + rev=$(git-rev-parse --verify "refs/heads/$arg^0") branch="$arg" fi + new="$rev" elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null) then # checking out selected paths from a tree-ish. diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 5fa6a45577..ed2e9ee3c6 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -190,4 +190,44 @@ test_expect_success 'checkout to detach HEAD with HEAD^0' ' fi ' +test_expect_success 'checkout with ambiguous tag/branch names' ' + + git tag both side && + git branch both master && + git reset --hard && + git checkout master && + + git checkout both && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + name=$(git symbolic-ref HEAD 2>/dev/null) && + test "z$name" = zrefs/heads/both + +' + +test_expect_success 'checkout with ambiguous tag/branch names' ' + + git reset --hard && + git checkout master && + + git tag frotz side && + git branch frotz master && + git reset --hard && + git checkout master && + + git checkout tags/frotz && + H=$(git rev-parse --verify HEAD) && + S=$(git show-ref -s --verify refs/heads/side) && + test "z$H" = "z$S" && + if name=$(git symbolic-ref HEAD 2>/dev/null) + then + echo "Bad -- should have detached" + false + else + : happy + fi + +' + test_done |