我设置了一个分支来跟踪ref in origin。 git checkout <branchname>
会切换到该分支,而git status
会显示我的分支距离原点前后多远,但我很惊讶origin/HEAD
仍指向origin/master
,而不是origin/<branchname>
所以我的问题是,在什么情况下,起源/ HEAD会被移动?
编辑:
我很欣赏如何移动origin / HEAD的答案,但我对“有机”移动它感兴趣,除了我明确告诉它这样做。
例如,当我切换分支时,git使HEAD指向我正在检出的分支,所以我很惊讶origin / HEAD不会以相同的方式移动。
答案 0 :(得分:149)
首先请注意,您的问题显示出一些误解。 origin / HEAD表示远程上的默认分支,即您正在呼叫原点的远程存储库中的HEAD。当您在回购中切换分支时,您不会影响它。远程分支也是如此;您的仓库中可能包含master
和origin/master
,其中origin/master
表示远程存储库中master
分支的本地副本。
来源的HEAD只会在您或其他人在远程存储库中实际更改时发生变化,这基本上永远不会发生 - 您希望默认分支公共仓库在稳定分支上保持不变(可能是主人)。 origin / HEAD是一个本地引用,表示远程存储库中HEAD的本地副本。(其全名为refs / remotes / origin / HEAD。)
我认为以上内容回答了您真正想知道的内容,但是继续回答您明确要求的问题...在克隆存储库时会自动设置origin / HEAD,这就是它。奇怪的是,它是由<{1}}之类的命令设置的 - 我相信它改变的唯一方法就是手动更改它。 (通过更改,我的意思是指向另一个分支;显然,如果该分支发生更改,则指向更改的提交,这可能发生在fetch / pull / remote update上。)
修改:下面讨论的问题已在 Git 1.8.4.3 中得到纠正;见this update。
git remote update
的输出中看到这个:
git remote show origin
奇怪的是,虽然如果遥控器上的内容发生变化,以这种方式打印的HEAD概念会发生变化(例如,如果foo被移除),它实际上并不会更新$ git remote show origin
* remote origin
Fetch URL: ...
Push URL: ...
HEAD branch (remote HEAD is ambiguous, may be one of the following):
foo
master
。这可能导致非常奇怪的情况。假设在上面的例子中,origin / HEAD实际上指向了foo,然后删除了origin的foo分支。然后我们可以这样做:
refs/remotes/origin/HEAD
因此即使远程节目知道HEAD是主节目,它也不会更新任何内容。正确修剪过时的foo分支,并且HEAD变为悬空(指向不存在的分支),并且仍不会将其更新为指向主分支。如果要解决此问题,请使用$ 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)
,它会自动确定上面的原点HEAD,然后实际设置origin / HEAD指向相应的远程分支。
答案 1 :(得分:59)
这是您作为本地仓库所有者的设置。改变它:
git remote set-head origin some_branch
而origin / HEAD将指向您的分支而不是主分支。这将仅适用于您的回购,而不适用于其他回购。默认情况下,它将指向master,除非在远程仓库上配置了其他内容。
Manual entry for remote set-head提供了一些很好的信息。
编辑:强调:没有你告诉它,它“移动”的唯一方法就是像renaming the master branch这样的情况,我认为这不是“有机”的。所以,我会说有机地它不动。
答案 2 :(得分:20)
什么使“/ HEAD”有机地移动?
git clone
将其设置为HEAD在原点的位置
git clone
HEAD on origin代表什么?
git clone
以这种方式使用它什么设置起源/ HEAD?
git clone
抓取并设置git fetch
像其他任何引用一样更新它,那就没有意义,但它不会git remote set-head origin -a
抓取并设置它
<强>琐事强>
origin/HEAD
也可以在不联系遥控器的情况下设置为任何其他值:git remote set-head origin <branch>
答案 3 :(得分:10)
免责声明:这是Jefromi's answer的更新,我写这篇文章是为了挽救好奇的时间。
我徒劳地试图复制(在Git 2.0.1中)Jefromi在他的回答中提到的remote HEAD is ambiguous
消息;所以我做了一些挖掘(通过克隆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.
(提交4229f1fa325870d6b24fe2a4c7d2ed5f14c6f771
,日期为2009年2月27日,与git log --reverse --grep="HEAD is ambiguous"
)
然而,此后的歧义已被解除:
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.
(提交9196a2f8bd46d36a285bdfa03b4540ed3f01f671
,日期为2013年11月8日,与git log --grep="ambiguous" --grep="HEAD" --all-match
)
修改(感谢torek):
$ git name-rev --name-only 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
tags/v1.8.4.3~3
这意味着,如果您使用 Git v1.8.4.3或更高版本,则不应遇到任何模糊的远程HEAD问题。
答案 4 :(得分:8)
请记住,我们正在讨论两个独立的git回购。您的本地仓库包含您的代码,而远程运行在其他地方。
你是对的,当你改变一个分支时,HEAD指向你当前的分支。所有这一切都发生在你当地的git repo上。不是远程仓库,可能由另一个开发人员拥有,或者位于办公室的服务器上,或github,或文件系统上的其他目录,等等......
您的计算机(本地存储库)没有业务更改远程git仓库上的HEAD指针。例如,它可能由不同的开发人员拥有。
还有一件事,您的计算机调用源/ XXX是您的计算机在最后一次获取时对远程状态的理解。
那么“有机”更新origin / HEAD会是什么?这将是远程git仓库的活动。不是你当地的回购。
人们提到了
git symbolic-ref HEAD refs / head / my_other_branch
通常,当服务器上有共享的中央git仓库供开发团队使用时,可以使用它。它将是在远程计算机上执行的命令。你会在远程git repo上看到这个活动。
答案 5 :(得分:1)
从git CLI运行以下命令:
# move to the wanted commit
git reset --hard <commit-hash>
# update remote
git push --force origin <branch-name>
答案 6 :(得分:0)
它由 git clone
和 git remote add -m master $url
设置。除此之外,您必须手动设置。
我也发送了一些补丁以使用 git fetch
进行更新(取决于某些配置)。在我看来,这将是更新它的最有机的方式。不幸的是,它们尚未合并。