为什么 `master` 和 `heads/master` 有区别?
Why is there a difference between `master` and `heads/master`?
我正在编写一个 shell 脚本,它切换到指定的提交,复制 /tmp
中的索引,将 HEAD
重置为原始位置,然后 运行s 临时目录中的命令:
orig_head=$(git rev-parse -q HEAD) # "refs/heads/master"
git checkout ""
# copy index to /tmp/...
git checkout "$orig_head"
# run command in /tmp/...
然而,这个脚本给了我相同的“'detached HEAD' state”消息,就像我 运行 git checkout refs/heads/master
:
Note: checking out 'refs/heads/master'.
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.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at c82ad67... Use vector and binary search for dictionary
如何正确存储和恢复 HEAD
的位置?
我宁愿避免使用 reset HEAD@{1}
,因为那看起来很乱。
大多数 git 命令并不真正关心名称是否为分支名称。明显的例外(可能还有更多,这些超出了我的想象)是 git branch
,当然还有 git checkout
.
对于非例外情况,gitrevisions
中列出了将分支名称解析为 SHA-1 的规则。对于 git branch
更容易:一些参数显然是分支名称,例如,在 git branch new/branch/name
中,new/branch/name
是一个分支名称,即使它可能还不存在。
checkout
命令无法做到这一点:给定 git checkout xyz
,xyz
可能是分支名称、标记名称或 [= 中的任何其他形式37=]。当然,要成为像 HEAD~5
这样有趣的语法形式之一,它必须在其中包含特殊的 ~
字符,但即使是朴素的名称也可能是分支名称,也可能不是。 (如果它跟在 -b
之后,如 git checkout -b new/branch
那么 is 绝对是一个分支名称,但这里不是这种情况。)
无论如何,简短的回答是 git checkout
有自己的特殊规则,与 gitrevisions
中列出的不同:如果名称在前面加上 refs/heads/
则为分支名称把它变成一个现有的分支名称。
由于 refs/heads/refs/heads/master
不是现有的分支名称,因此 refs/heads/master
失败。1 因此您需要删除 refs/heads/
部分你自己。
您可以在事后执行此操作,但有一个更简单的版本:git symbolic-ref
有 --short
将 refs/heads/
部分关闭。由于 HEAD
应该 只是对分支的符号引用(例如,绝不是对标记的符号引用),并且您知道您正在查询 HEAD
, 只需做:
orig_head=$(git symbolic-ref -q --short HEAD)
你还需要一点,那就是记住系统是否处于分离的 HEAD 状态,如果是,那么它的 SHA-1 是什么。所以:
sha1=$(git rev-parse HEAD) || exit 1 # should never fail
orig_head=$(git symbolic-ref -q --short HEAD) && symbolic=true || symbolic=false
或类似的东西。
1您可以创建这样一个分支。不。 :-)
master是一种指针,指向master分支的最新提交。
而 refs/heads/master 是一种历史跟踪器,它跟踪 master 指针的活动,如提交、切换到其他分支,在 github 等
上推送 master 分支
我正在编写一个 shell 脚本,它切换到指定的提交,复制 /tmp
中的索引,将 HEAD
重置为原始位置,然后 运行s 临时目录中的命令:
orig_head=$(git rev-parse -q HEAD) # "refs/heads/master"
git checkout ""
# copy index to /tmp/...
git checkout "$orig_head"
# run command in /tmp/...
然而,这个脚本给了我相同的“'detached HEAD' state”消息,就像我 运行 git checkout refs/heads/master
:
Note: checking out 'refs/heads/master'.
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.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at c82ad67... Use vector and binary search for dictionary
如何正确存储和恢复 HEAD
的位置?
我宁愿避免使用 reset HEAD@{1}
,因为那看起来很乱。
大多数 git 命令并不真正关心名称是否为分支名称。明显的例外(可能还有更多,这些超出了我的想象)是 git branch
,当然还有 git checkout
.
对于非例外情况,gitrevisions
中列出了将分支名称解析为 SHA-1 的规则。对于 git branch
更容易:一些参数显然是分支名称,例如,在 git branch new/branch/name
中,new/branch/name
是一个分支名称,即使它可能还不存在。
checkout
命令无法做到这一点:给定 git checkout xyz
,xyz
可能是分支名称、标记名称或 [= 中的任何其他形式37=]。当然,要成为像 HEAD~5
这样有趣的语法形式之一,它必须在其中包含特殊的 ~
字符,但即使是朴素的名称也可能是分支名称,也可能不是。 (如果它跟在 -b
之后,如 git checkout -b new/branch
那么 is 绝对是一个分支名称,但这里不是这种情况。)
无论如何,简短的回答是 git checkout
有自己的特殊规则,与 gitrevisions
中列出的不同:如果名称在前面加上 refs/heads/
则为分支名称把它变成一个现有的分支名称。
由于 refs/heads/refs/heads/master
不是现有的分支名称,因此 refs/heads/master
失败。1 因此您需要删除 refs/heads/
部分你自己。
您可以在事后执行此操作,但有一个更简单的版本:git symbolic-ref
有 --short
将 refs/heads/
部分关闭。由于 HEAD
应该 只是对分支的符号引用(例如,绝不是对标记的符号引用),并且您知道您正在查询 HEAD
, 只需做:
orig_head=$(git symbolic-ref -q --short HEAD)
你还需要一点,那就是记住系统是否处于分离的 HEAD 状态,如果是,那么它的 SHA-1 是什么。所以:
sha1=$(git rev-parse HEAD) || exit 1 # should never fail
orig_head=$(git symbolic-ref -q --short HEAD) && symbolic=true || symbolic=false
或类似的东西。
1您可以创建这样一个分支。不。 :-)
master是一种指针,指向master分支的最新提交。
而 refs/heads/master 是一种历史跟踪器,它跟踪 master 指针的活动,如提交、切换到其他分支,在 github 等
上推送 master 分支