git origin/HEAD 如何设置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8839958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does origin/HEAD get set?
提问by ecoffey
I have a branch set up to track a ref in origin. git checkout <branchname>
switches to that branch, and a git status
will show me how far ahead or behind my branch is from origin, but I'm surprised that origin/HEAD
still points at origin/master
, and not origin/<branchname>
我设置了一个分支来跟踪原始引用。 git checkout <branchname>
切换到那个分支,agit status
将显示我的分支距原点多远或多远,但我很惊讶它origin/HEAD
仍然指向origin/master
,而不是origin/<branchname>
So my question is, under what circumstances does origin/HEAD get moved?
所以我的问题是,在什么情况下 origin/HEAD 会被移动?
EDIT:
编辑:
I appreciate the answers about howto move origin/HEAD, but I'm interested in what "organically" moves it, outside of me explicitly telling it to do so.
我很欣赏有关如何移动原点/HEAD的答案,但我对“有机”移动它的内容感兴趣,除了我明确告诉它这样做之外。
For example, when I switch branches, git makes HEAD point at the branch I'm checking out, so I'm surprised that origin/HEAD doesn't move in the same manner.
例如,当我切换分支时,git 使 HEAD 指向我正在检查的分支,所以我很惊讶 origin/HEAD 没有以相同的方式移动。
回答by Cascabel
Note first that your question shows a bit of misunderstanding. origin/HEAD represents the default branch on the remote, i.e. the HEAD that's in that remote repository you're calling origin. When you switch branches in your repo, you're not affecting that. The same is true for remote branches; you might have master
and origin/master
in your repo, where origin/master
represents a local copy of the master
branch in the remote repository.
首先请注意,您的问题显示出一些误解。origin/HEAD 表示 remote 上的默认分支,即您正在调用 origin 的远程存储库中的 HEAD。当你在你的仓库中切换分支时,你不会影响它。远程分支也是如此;您可能在您的存储库中拥有master
和origin/master
,其中origin/master
代表master
远程存储库中分支的本地副本。
origin's HEAD will only change if you or someone else actually changes it in the remote repository, which should basically never happen - you want the default branch a public repo to stay constant, on the stable branch (probably master). origin/HEAD is a local ref representing a local copy of the HEAD in the remote repository.(Its full name is refs/remotes/origin/HEAD.)
仅当您或其他人在远程存储库中实际更改它时, origin 的 HEAD 才会更改,这基本上永远不会发生 - 您希望公共存储库的默认分支在稳定分支(可能是 master)上保持不变。origin/HEAD 是一个本地引用,代表远程存储库中 HEAD 的本地副本。(它的全名是 refs/remotes/origin/HEAD。)
I think the above answers what you actually wanted to know, but to go ahead and answer the question you explicitly asked... origin/HEAD is set automatically when you clone a repository, and that's about it. Bizarrely, that it's notset by commands like git remote update
- I believe the only way it will change is if you manually change it. (By change I mean point to a different branch; obviously the commit it points to changes if that branch changes, which might happen on fetch/pull/remote update.)
我认为以上回答了您真正想知道的问题,但要继续回答您明确提出的问题... origin/HEAD 在您克隆存储库时会自动设置,仅此而已。奇怪的是,它不是由像这样的命令设置的git remote update
- 我相信它会改变的唯一方法是你手动改变它。(更改我的意思是指向不同的分支;显然,如果该分支发生更改,则它指向的提交会发生更改,这可能发生在获取/拉取/远程更新时。)
Edit: The problem discussed below was corrected in Git 1.8.4.3; see this update.
编辑:下面讨论的问题已在Git 1.8.4.3中得到纠正;看到这个更新。
There is a tiny caveat, though. HEAD is a symbolic ref, pointing to a branch instead of directly to a commit, but the git remote transfer protocols only report commits for refs. So Git knows the SHA1 of the commit pointed to by HEAD and all other refs; it then has to deduce the value of HEAD by finding a branch that points to the same commit. This means that if two branches happen to point there, it's ambiguous. (I believe it picks master if possible, then falls back to first alphabetically.) You'll see this reported in the output of git remote show origin
:
不过,有一个小小的警告。HEAD 是一个符号引用,指向一个分支而不是直接指向一个提交,但是 git 远程传输协议只报告引用的提交。所以 Git 知道 HEAD 和所有其他引用指向的提交的 SHA1;然后它必须通过找到指向同一提交的分支来推断 HEAD 的值。这意味着如果两个分支碰巧指向那里,它是不明确的。(我相信它会尽可能选择 master,然后按字母顺序回退到第一个。)您会在输出中看到这一点git remote show origin
:
$ git remote show origin
* remote origin
Fetch URL: ...
Push URL: ...
HEAD branch (remote HEAD is ambiguous, may be one of the following):
foo
master
Oddly, although the notion of HEAD printed this way will change if things change on the remote (e.g. if foo is removed), it doesn't actually update refs/remotes/origin/HEAD
. This can lead to really odd situations. Say that in the above example origin/HEAD actually pointed to foo, and origin's foo branch was then removed. We can then do this:
奇怪的是,虽然以这种方式打印的 HEAD 的概念会随着遥控器上的事情发生变化(例如,如果 foo 被删除)而改变,但它实际上并没有更新refs/remotes/origin/HEAD
。这可能会导致非常奇怪的情况。假设在上面的示例中 origin/HEAD 实际上指向 foo,然后 origin 的 foo 分支被删除。然后我们可以这样做:
$ git remote show origin
...
HEAD branch: master
$ git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/foo
$ git remote update --prune origin
Fetching origin
x [deleted] (none) -> origin/foo
(refs/remotes/origin/HEAD has become dangling)
So even though remote show knows HEAD is master, it doesn't update anything. The stale foo branch is correctly pruned, and HEAD becomes dangling (pointing to a nonexistent branch), and it stilldoesn't update it to point to master. If you want to fix this, use git remote set-head origin -a
, which automatically determines origin's HEAD as above, and then actually sets origin/HEAD to point to the appropriate remote branch.
因此,即使远程显示知道 HEAD 是主控,它也不会更新任何内容。陈旧的 foo 分支被正确修剪,并且 HEAD 变得悬空(指向一个不存在的分支),并且它仍然没有更新它以指向 master。如果你想解决这个问题,使用git remote set-head origin -a
,它会自动确定原点的 HEAD,然后实际设置原点/HEAD 指向适当的远程分支。
回答by eis
It is your setting as the owner of your local repo. Change it like this:
这是您作为本地存储库所有者的设置。像这样改变它:
git remote set-head origin some_branch
And origin/HEAD will point to your branch instead of master. This would then apply to your repo only and not for others. By default, it will point to master, unless something else has been configured on the remote repo.
并且 origin/HEAD 将指向您的分支而不是 master。这将仅适用于您的回购,而不适用于其他回购。默认情况下,它将指向 master,除非在远程 repo 上配置了其他内容。
Manual entry for remote set-headprovides some good information on this.
远程机头的手动输入为此提供了一些很好的信息。
Edit: to emphasize: without you telling it to, the only way it would "move" would be a case like renaming the master branch, which I don't think is considered "organic". So, I would say organically it does not move.
编辑:强调:如果没有你告诉它,它“移动”的唯一方法就是重命名 master 分支,我认为这不被认为是“有机的”。所以,我会说它有机地不动。
回答by Robert Siemer
What moves origin/HEAD "organically"?
什么“有机地”移动原点/头部?
git clone
sets it once to the spot where HEAD is on origin- it serves as the default branch to checkout after cloning with
git clone
- it serves as the default branch to checkout after cloning with
git clone
将其设置一次到 HEAD 位于原点的位置- 它用作克隆后结帐的默认分支
git clone
- 它用作克隆后结帐的默认分支
What does HEAD on origin represent?
原点上的 HEAD 代表什么?
- on bare repositories (often repositories “on servers”) it serves as a marker for the default branch, because
git clone
uses it in such a way - on non-bare repositories (local or remote), it reflects the repository's current checkout
- 在裸存储库(通常是“服务器上”的存储库)上,它用作默认分支的标记,因为
git clone
以这种方式使用它 - 在非裸存储库(本地或远程)上,它反映了存储库的当前检出
What sets origin/HEAD?
什么设置原点/头部?
git clone
fetches and sets it- it would make sense if
git fetch
updates it like any other reference, but it doesn't git remote set-head origin -a
fetches and sets it- useful to update the local knowledge of what remote considers the “default branch”
git clone
获取并设置它- 如果
git fetch
像任何其他参考一样更新它是有意义的,但它没有 git remote set-head origin -a
获取并设置它- 用于更新远程认为“默认分支”的本地知识
Trivia
琐事
origin/HEAD
can also be set to any other value without contacting the remote:git remote set-head origin <branch>
- I see no use-case for this, except for testing
- unfortunately nothing is able to set HEAD on the remote
- older versions of git did not know which branch HEAD points to on the remote, only which commit hash it finally has: so it just hopefully picked a branch name pointing to the same hash
origin/HEAD
也可以在不联系遥控器的情况下设置为任何其他值:git remote set-head origin <branch>
- 除了测试,我看不到任何用例
- 不幸的是,没有什么能够在遥控器上设置 HEAD
- 旧版本的 git 不知道 HEAD 指向远程的哪个分支,只知道它最终拥有哪个提交哈希:所以它只是希望选择一个指向相同哈希的分支名称
回答by jub0bs
Disclaimer: this is an update to Jefromi's answer, which I'm writing to save the curious some time.
免责声明:这是Jefromi 的回答的更新,我写这篇文章是为了节省一些时间。
I tried in vain to replicate (in Git 2.0.1) the remote HEAD is ambiguous
message that Jefromi mentions in his answer; so I did a bit of digging (by cloning https://github.com/git/gitand searching the log). It used to be that
我试图复制(在 Git 2.0.1 中)remote HEAD is ambiguous
Jefromi 在他的回答中提到的消息,但徒劳无功;所以我做了一些挖掘(通过克隆https://github.com/git/git并搜索日志)。以前是这样
Determining HEAD is ambiguous since it is done by comparing SHA1s. In the case of multiple matches we return refs/heads/master if it matches, else we return the first match we encounter. builtin-remote needs all matches returned to it, so add a flag for it to request such.
Determining HEAD is ambiguous since it is done by comparing SHA1s. In the case of multiple matches we return refs/heads/master if it matches, else we return the first match we encounter. builtin-remote needs all matches returned to it, so add a flag for it to request such.
(Commit 4229f1fa325870d6b24fe2a4c7d2ed5f14c6f771
, dated Feb 27, 2009, found with git log --reverse --grep="HEAD is ambiguous"
)
(提交4229f1fa325870d6b24fe2a4c7d2ed5f14c6f771
,日期为 2009 年 2 月 27 日,发现于git log --reverse --grep="HEAD is ambiguous"
)
However, the ambiguity in question has since been lifted:
然而,有关的歧义已被解除:
One long-standing flaw in the pack transfer protocol used by "git clone" was that there was no way to tell the other end which branch "HEAD" points at, and the receiving end needed to guess. A new capability has been defined in the pack protocol to convey this information so that cloning from a repository with more than one branches pointing at the same commit where the HEAD is at now reliably sets the initial branch in the resulting repository.
One long-standing flaw in the pack transfer protocol used by "git clone" was that there was no way to tell the other end which branch "HEAD" points at, and the receiving end needed to guess. A new capability has been defined in the pack protocol to convey this information so that cloning from a repository with more than one branches pointing at the same commit where the HEAD is at now reliably sets the initial branch in the resulting repository.
(Commit 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
, dated Nov 8, 2013, found with git log --grep="ambiguous" --grep="HEAD" --all-match
)
(提交9196a2f8bd46d36a285bdfa03b4540ed3f01f671
,日期为 2013 年 11 月 8 日,发现于git log --grep="ambiguous" --grep="HEAD" --all-match
)
Edit(thanks to torek):
编辑(感谢torek):
$ git name-rev --name-only 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
tags/v1.8.4.3~3
This means that, if you're using Git v1.8.4.3 or later, you shouldn't run into any ambiguous-remote-HEAD problem.
这意味着,如果您使用Git v1.8.4.3 或更高版本,您不应该遇到任何歧义远程 HEAD 问题。
回答by Pablo Maurin
Remember there are twoindependent git repos we are talking about. Your local repo with your code and the remote running somewhere else.
请记住,我们正在谈论两个独立的 git 存储库。带有代码的本地存储库和在其他地方运行的远程存储库。
Your are right, when you change a branch, HEAD points to your current branch. All of this is happening on your local git repo. Not the remote repo, which could be owned by another developer, or siting on a sever in your office, or github, or another directory on the filesystem, or etc...
你是对的,当你改变一个分支时, HEAD 指向你当前的分支。所有这些都发生在您本地的 git 存储库中。不是远程仓库,它可能由另一个开发人员拥有,或者位于您办公室的服务器上,或者 github 上,或者文件系统上的另一个目录,等等......
Your computer (local repo) has no business changing the HEAD pointer on the remote git repo. It could be owned by a different developer for example.
您的计算机(本地存储库)无法更改远程 git 存储库上的 HEAD 指针。例如,它可能由不同的开发人员拥有。
One more thing, what your computer calls origin/XXX is your computer's understanding of the state of the remote at the time of the last fetch.
还有一件事,您的计算机所称的 origin/XXX 是您的计算机对最后一次获取时远程状态的理解。
So what would "organically" update origin/HEAD? It would be activity on the remote git repo. Not your local repo.
那么什么会“有机地”更新 origin/HEAD 呢?这将是远程 git repo 上的活动。不是您的本地回购。
People have mentioned
人们已经提到
git symbolic-ref HEAD refs/head/my_other_branch
git 符号引用 HEAD refs/head/my_other_branch
Normally, that is used when there is a shared central git repo on a server for use by the development team. It would be a command executed on the remote computer. You would see this as activity on the remote git repo.
通常,当服务器上有共享的中央 git 存储库供开发团队使用时使用。这将是在远程计算机上执行的命令。您会将此视为远程 git 存储库上的活动。
回答by Yakir GIladi Edry
Run the following commands from git CLI:
从 git CLI 运行以下命令:
# move to the wanted commit
git reset --hard <commit-hash>
# update remote
git push --force origin <branch-name>