我有一个本地分支“master”跟踪远程分支“origin / master”。
当我像这样结账大师时:
git checkout refs/heads/master
我最终得到了一个独立的HEAD:
注意:检查'refs / heads / master'。
你处于'超级HEAD'状态。你可以环顾四周,做实验 更改并提交它们,您可以放弃您在此中提交的任何提交 通过执行另一次结账而不影响任何分支的状态。
显然我可以结账“主人”,但这恰好是一个含糊不清的参考。我只想知道消除分支名称歧义的“git方式”是什么,而不分离HEAD。
答案 0 :(得分:1)
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
的ref而不是refs/heads/master
。
git checkout
命令功能多样,方便,但在master
与refs/heads/master
等情况下可能会造成混淆。当您指定master
并且名为refs/heads/master
的引用存在时,git checkout
会假定您指的是master
分支,而不是master
指向的修订。当您指定refs/heads/master
并且名为refs/heads/refs/heads/master
的引用不存在时,git checkout
假定您指的是master
指向的修订,而不是名为{{1的分支(因此你得到一个分离的refs/heads/master
)。
如果你想查看其他短名称也是HEAD
的其他引用(例如名为master
的标记),你必须拼出完整的引用名称(例如,{{ 1}})或以不能被解释为有效分支名称的方式拼写修订版(例如,master
)。后者导致git checkout refs/tags/master
遵循git checkout master^0
:
当含糊不清时,
git checkout
通过以下规则中的第一场比赛消除歧义:
- 如果
git help revisions
存在,那就是您的意思(这通常仅适用于<refname>
,$GIT_DIR/<refname>
,HEAD
,FETCH_HEAD
和{{1 }});- 否则,
ORIG_HEAD
如果存在;- 否则,
MERGE_HEAD
如果存在;- 否则,
CHERRY_PICK_HEAD
如果存在;- 否则,
refs/<refname>
如果存在;- 否则,
醇>refs/tags/<refname>
如果存在。
当然结果将是一个分离的refs/heads/<refname>
,但是当你签出一个非分支时总会发生这种情况。