3

我有一个本地分支“master”跟踪远程分支“origin/master”。

当我像这样结帐大师时:

git checkout refs/heads/master

我最终得到了一个分离的 HEAD:

注意:签出'refs/heads/master'。

您处于“分离 HEAD”状态。您可以环顾四周,进行实验性更改并提交它们,并且您可以放弃在此状态下所做的任何提交,而不会通过执行另一个签出来影响任何分支。

显然我可以只签出“master”,但这恰好是一个模棱两可的参考。我只想知道消除分支名称歧义的“git方式”是什么,而不分离HEAD。

4

1 回答 1

2

的文档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 的歧义:

  1. 如果$GIT_DIR/<refname>存在,这就是你的意思(这通常只对HEAD, FETCH_HEAD, ORIG_HEAD,MERGE_HEAD和有用CHERRY_PICK_HEAD);
  2. 否则,refs/<refname>如果存在;
  3. 否则,refs/tags/<refname>如果存在;
  4. 否则,refs/heads/<refname>如果存在;
  5. 否则,refs/remotes/<refname>如果存在;
  6. 否则,refs/remotes/<refname>/HEAD如果它存在。

当然,结果将是 detached HEAD,但是当您签出非分支时总是会发生这种情况。

于 2014-09-12T06:39:30.043 回答