如果我仅使用分支名称签出分支,HEAD则更新为指向该分支.
$ git checkout branch
Switched to branch 'branch'
Run Code Online (Sandbox Code Playgroud)
如果我使用refs/heads/branch或签出分支heads/branch,则HEAD变为分离.
$ git checkout refs/heads/branch
Note: checking out 'refs/heads/branch'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
$ git checkout "refs/heads/branch"
Same result
$ git checkout heads/branch
Same result
Run Code Online (Sandbox Code Playgroud)
为什么?如果它的版本依赖,我在Ubuntu 12.04.3上有git 1.7.9.5.
tor*_*rek 17
该checkout命令区分了两种情况(好吧,实际上是"很多",但让我们从两种情况开始:-)):
git checkout branch.git checkout 6240c5c.(就个人而言,我认为这些应该使用不同的命令名称,但这只是我.另一方面,它会消除下面描述的所有奇怪.)
现在,让我们说你想要前者.只需写出分支名称就可以了refs/heads/.
如果你想要后者,你可以通过gitrevisions中列出的任何方法指定修订版,除了导致"进入分支"的任何方法.
无论出于何种原因,这里选择的算法 - 它在手册页中记录,在<branch>-is 下:如果你写了一个名字,当添加refs/heads/它时,命名一个分支,git checkout将把你"放在那个分支上".如果您指定或,它将在reflog中查找第N个旧分支(含义).否则它会选择第二种方法,为您提供"分离的HEAD".@{-N}-HEAD-@{-1} 即使名称是gitrevisions中建议的用于避免歧义的名称,即heads/xyz当存在另一个名称时,也是如此xyz.(但是:你可以添加--detach以避免"进入分支"的情况,即使它会进入分支机构.)
这也与gitrevisions文档中列出的解决规则相矛盾.为了证明这一点(虽然很难看到),我制作了一个同名的标签和分支,derp2:
$ git checkout derp2
warning: refname 'derp2' is ambiguous.
Previous HEAD position was ...
Switched to branch 'derp2'
Run Code Online (Sandbox Code Playgroud)
这使我成为分支,而不是分离和转向标记的修订.
$ git show derp2
warning: refname 'derp2' is ambiguous.
...
Run Code Online (Sandbox Code Playgroud)
这向我展示了标记版本,gitrevisions表示它应该如此.
一方面注意:"进入分支"实际上意味着"将分支名称的符号引用放入HEADgit目录中指定的文件".符号引用是文字文本ref:(带尾随空格),后跟完整的分支名称,例如refs/heads/derp2.似乎有点不一致,git checkout要求没有refs/heads/零件的名称才能添加ref: refs/heads/零件,但那是你的git.:-)可能有一些历史原因:最初,作为一个符号引用,该HEAD文件实际上是分支文件的符号链接,它始终是一个文件.这些天,部分是因为Windows,部分是因为代码演变,它有文字ref:字符串,并且引用可能变得"打包",因此无论如何都不能作为单独的文件提供.
相反,"分离的HEAD"实际上意味着"将原始SHA-1放入HEAD文件中".除了在此文件中具有数值之外,git的行为与"在分支上"时的行为方式相同:添加新提交仍然有效,新提交的父级是当前提交.合并仍然可以完成,合并提交的父项是当前和将要合并的提交.该HEAD文件与每个新的更新承诺,因为它发生.1 在任何时候,您都可以创建一个指向当前提交的新分支或标记标签,以便即使在您关闭"分离的HEAD"之后也可以保留新的提交链以防止将来的垃圾收集; 或者你可以简单地切换掉,让新的提交,如果有的话,用通常的垃圾收集取出.(请注意,HEADreflog会在一段时间内阻止这种情况,我认为默认为30天.)
[ 1如果你"在一个分支上",同样的自动更新发生,它恰好发生在HEAD引用的分支上.也就是说,如果你在分支上B并且你添加了一个新的提交,HEAD仍然会说ref: refs/heads/B,但现在你得到的提交ID就是你刚刚添加的新提交.这就是分支"增长"的方式:在"分支"上添加新提交会导致分支引用自动向前移动.同样,当处于"分离的HEAD"状态时,新的提交会导致自动向前移动.git rev-parse BHEAD
为了完整起见,这里列出了其他事情git checkout可以做的事情,如果我有这样的权力,我可能会把它放在各种单独的命令中:
git checkout revspec -- path ...git checkout -b newbranch加上选项git branch)git checkout --orphan(这使你"上的一个分支"是不存在的,即,写入到但不创建分支,这是还有一个未出生的分支在新的存储库中)ref: refs/heads/branch-nameHEADbranch-namemastergit checkout -m ...git checkout --ours,git checkout --theirsgit add --patch:git checkout --patch| 归档时间: |
|
| 查看次数: |
7879 次 |
| 最近记录: |