为什么`master`和`heads/master`之间有区别? [英] Why is there a difference between `master` and `heads/master`?

查看:118
本文介绍了为什么`master`和`heads/master`之间有区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个shell脚本,该脚本将切换到指定的提交,在/tmp中创建索引的副本,将HEAD重置为原始位置,然后在临时目录中运行命令:

I'm writing a shell script which switches to a specified commit, makes a copy of the index in /tmp, resets HEAD to original position, then runs a command in the temporary directory:

orig_head=$(git rev-parse -q HEAD)  # "refs/heads/master"
git checkout "$1"
# copy index to /tmp/...
git checkout "$orig_head"
# run command in /tmp/...

但是,此脚本为我提供了与运行git checkout refs/heads/master时相同的分离头状态"消息:

However, this script gives me the same "'detached HEAD' state" message as when I run 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的位置?

How can I store and restore the position of HEAD properly?

我宁愿避免使用reset HEAD@{1},因为这看起来很混乱.

I would prefer to avoid using reset HEAD@{1}, as that seems messy.

推荐答案

大多数git命令实际上并不关心名称是否为分支名称.明显的例外(可能更多,这些不在我的脑海中)是git branch,当然还有git checkout.

Most git commands don't really care whether a name is a branch name. The obvious exceptions (there may be more, these are off the top of my head) are git branch and, of course, git checkout.

对于非例外情况,将分支名称解析为SHA-1的规则在

For the non-exceptions, the rules for resolving branch names to SHA-1s are listed in gitrevisions. For git branch it's easier: some arguments are obviously branch-names, e.g., in git branch new/branch/name, new/branch/name is a branch name, even though it presumably doesn't exist yet.

checkout命令无法执行此操作:给定git checkout xyzxyz可能是分支名称或标记名称,或

The checkout command can't do that: given git checkout xyz, xyz might be a branch name, or a tag name, or any of the other forms in gitrevisions. Of course, to be one of the funny syntax forms like HEAD~5 it has to have the special ~ character in it, but even an unadorned name might be a branch name, or might not. (If it follows -b, as in git checkout -b new/branch then is is definitely a branch-name, but that's not the case here.)

无论如何,简短的答案是git checkout有其自己的特殊规则,与

Anyway, the short answer is that git checkout has its own special rules, different from those listed in gitrevisions: a name is a branch name if adding refs/heads/ in front works to turn it into an existing branch name.

由于refs/heads/refs/heads/master不是现有的分支名称,因此此操作失败,并显示refs/heads/master. 1 因此,您需要自己剥离refs/heads/部分.

This fails with refs/heads/master since refs/heads/refs/heads/master is not an existing branch name.1 Hence you need to strip off the refs/heads/ part yourself.

您可以事后进行此操作,但是有一个更简单的版本:git symbolic-ref具有--short可以保留refs/heads/部分.由于HEAD 应该仅是对分支的符号引用(例如,永远都不是对标记的符号引用),并且您知道自己正在查询HEAD,因此只需执行以下操作:

You could do this after-the-fact, but there's an easier version: git symbolic-ref has --short to leave the refs/heads/ part off. Since HEAD should only be a symbolic reference to a branch (never a symbolic ref to a tag for instance), and you know you're inquiring about HEAD, just do:

orig_head=$(git symbolic-ref -q --short HEAD)

您还需要一点一点,那就是要记住系统是否以分离的HEAD状态开始,如果是,还附带什么SHA-1.所以:

You do need one more bit, which is to remember whether the system was in detached HEAD state to start with, and if so, what SHA-1 that goes with. So:

sha1=$(git rev-parse HEAD) || exit 1 # should never fail
orig_head=$(git symbolic-ref -q --short HEAD) && symbolic=true || symbolic=false

或类似的内容.

1 可以创建这样的分支.别. :-)

1You can create such a branch. Don't. :-)

这篇关于为什么`master`和`heads/master`之间有区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆