Jan*_*Jan 5 git git-detached-head
我有一个本地分支“master”跟踪远程分支“origin/master”。
当我像这样结账时:
git checkout refs/heads/master
Run Code Online (Sandbox Code Playgroud)
我最终得到了一个独立的头:
注意:查看“refs/heads/master”。
您处于“分离 HEAD”状态。您可以环顾四周,进行实验性更改并提交它们,并且可以通过执行另一次签出来放弃在此状态下所做的任何提交,而不会影响任何分支。
显然我可以直接查看“master”,但这恰好是一个不明确的参考。我只想知道在不分离 HEAD 的情况下消除分支名称歧义的“git 方式”是什么。
的文档git checkout没有说明它在master不明确时的行为方式。查看源代码(我快速浏览,所以我可能是错的),它看起来假设git checkout提供的名称(例如, )是一个分支名称,直到发现给定名称master没有引用。refs/heads/*
因此,当修订版不明确时检查分支的正确方法是省略refs/heads/,例如git checkout master。
请注意,指定分支和指定修订版(或其他对象)之间存在微妙但重要的区别。对于采用修订版(或一般对象)的命令和选项,除非不明确,否则指定master与指定相同。它也与指定 、 或指向的SHA1等相同。refs/heads/mastermastermaster^0master
对于采用分支的命令和选项(例如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,并且存在名为 的 ref 时refs/heads/master,git checkout假定您指的是分支,而不是指向的master修订版。master当您指定refs/heads/master,并且 name 的引用refs/heads/refs/heads/master不存在时,则git checkout假设您指的master是指向的修订版,而不是名为的分支refs/heads/master(因此您得到一个 detached HEAD)。
如果您想查看短名称也是的其他参考文献master(例如名为 的标签master),则必须拼写出完整的参考名称(例如,git checkout refs/tags/master)或以无法解释为的方式拼写修订版本有效的分支名称(例如,git checkout master^0)。后者导致git checkout遵循以下描述的消歧规则git help revisions:
当有歧义时,a
<refname>通过以下规则中的第一个匹配来消除歧义:
- 如果存在,那就是
$GIT_DIR/<refname>你的意思(这通常只对HEAD、FETCH_HEAD、ORIG_HEAD和有用);MERGE_HEADCHERRY_PICK_HEAD- 否则,
refs/<refname>如果存在的话;- 否则,
refs/tags/<refname>如果存在的话;- 否则,
refs/heads/<refname>如果存在的话;- 否则,
refs/remotes/<refname>如果存在的话;- 否则,
refs/remotes/<refname>/HEAD如果存在的话。
当然,结果将是 detached HEAD,但是当您签出非分支时总会发生这种情况。