的文档git checkout没有说明它在master模棱两可时的行为方式。查看源代码(我快速浏览,所以我可能错了),它看起来git checkout假设提供的名称(例如, )是一个分支名称,直到它发现给定名称master没有引用。refs/heads/*
因此,当修订不明确时检查分支的正确方法是refs/heads/去掉git checkout master.
分支与修订
请注意,指定分支和指定修订版(或其他对象)之间存在细微但重要的区别。对于采用修订版(或通用对象)的命令和选项,指定master与指定refs/heads/master除非master是模棱两可的。它也与指定master^0,或master指向的 SHA1 等相同。
对于带有分支的命令和选项(例如,git branch或--branches类似命令的选项git log),指定master与指定不同refs/heads/master。在这些情况下,完整的字符串refs/heads/master被解释为分支的名称,导致 Git 创建/检查/更新名为refs/heads/refs/heads/master而不是refs/heads/master.
该git checkout命令用途广泛,很方便,但在mastervs.之类的情况下可能会引起混淆refs/heads/master。当您指定master并且存在名为的 refrefs/heads/master时,git checkout假定您指的是master分支,而不是master指向的修订版。当您指定并且不存在refs/heads/master名为的 ref时,假设您指的是指向的修订版,而不是名为的分支(因此您得到一个 detached )。refs/heads/refs/heads/mastergit checkoutmasterrefs/heads/masterHEAD
模棱两可时检查非分支
如果您想查看其他一些短名称也是master(例如,名为 的标签master)的参考,您必须拼出完整的参考名称(例如,git checkout refs/tags/master)或以无法解释为的方式拼写修订版一个有效的分支名称(例如,git checkout master^0)。后者导致git checkout遵循以下中描述的消歧规则git help revisions:
当<refname>有歧义时,通过以下规则中的第一个匹配来消除 a 的歧义:
- 如果
$GIT_DIR/<refname>存在,这就是你的意思(这通常只对HEAD, FETCH_HEAD, ORIG_HEAD,MERGE_HEAD和有用CHERRY_PICK_HEAD);
- 否则,
refs/<refname>如果存在;
- 否则,
refs/tags/<refname>如果存在;
- 否则,
refs/heads/<refname>如果存在;
- 否则,
refs/remotes/<refname>如果存在;
- 否则,
refs/remotes/<refname>/HEAD如果它存在。
当然,结果将是 detached HEAD,但是当您签出非分支时总是会发生这种情况。