Skip to content

Commit 5035242

Browse files
committed
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 <[email protected]>
1 parent 23fcdc7 commit 5035242

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

git-checkout.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ while [ "$#" != "0" ]; do
6363
echo "unknown flag $arg"
6464
exit 1
6565
fi
66-
new="$rev"
6766
new_name="$arg"
6867
if git-show-ref --verify --quiet -- "refs/heads/$arg"
6968
then
69+
rev=$(git-rev-parse --verify "refs/heads/$arg^0")
7070
branch="$arg"
7171
fi
72+
new="$rev"
7273
elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null)
7374
then
7475
# checking out selected paths from a tree-ish.

t/t7201-co.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,44 @@ test_expect_success 'checkout to detach HEAD with HEAD^0' '
190190
fi
191191
'
192192

193+
test_expect_success 'checkout with ambiguous tag/branch names' '
194+
195+
git tag both side &&
196+
git branch both master &&
197+
git reset --hard &&
198+
git checkout master &&
199+
200+
git checkout both &&
201+
H=$(git rev-parse --verify HEAD) &&
202+
M=$(git show-ref -s --verify refs/heads/master) &&
203+
test "z$H" = "z$M" &&
204+
name=$(git symbolic-ref HEAD 2>/dev/null) &&
205+
test "z$name" = zrefs/heads/both
206+
207+
'
208+
209+
test_expect_success 'checkout with ambiguous tag/branch names' '
210+
211+
git reset --hard &&
212+
git checkout master &&
213+
214+
git tag frotz side &&
215+
git branch frotz master &&
216+
git reset --hard &&
217+
git checkout master &&
218+
219+
git checkout tags/frotz &&
220+
H=$(git rev-parse --verify HEAD) &&
221+
S=$(git show-ref -s --verify refs/heads/side) &&
222+
test "z$H" = "z$S" &&
223+
if name=$(git symbolic-ref HEAD 2>/dev/null)
224+
then
225+
echo "Bad -- should have detached"
226+
false
227+
else
228+
: happy
229+
fi
230+
231+
'
232+
193233
test_done

0 commit comments

Comments
 (0)