起源/ HEAD如何设置?

我有一个分支机构设置来跟踪起源的裁判。 git checkout <branchname>切换到该分支,并且git status将显示我的分支从原点git checkout <branchname>有多远,但是我很惊讶origin/HEAD仍指向origin/master点,而不是origin/<branchname>

所以我的问题是,在什么情况下起源/ HEAD被移动?

编辑:

我很欣赏关于如何移动origin / head的答案,但是我对“有机地”移动它感兴趣,在我之外明确地告诉它这样做。

例如,当我切换分支时,git使HEAD指向我正在检查的分支,所以我很惊讶原点/ HEAD不以相同的方式移动。

首先注意你的问题显示有点误解。 origin / HEAD表示远程的默认分支 ,即位于远程仓库中的HEAD。 当你在你的回购中切换分支,你不会影响。 远程分支也是如此; 您可能在您的仓库中拥有masterorigin/master ,其中origin/master代表远程仓库中master分支的本地副本。

如果你或者其他人在远程仓库中实际改变了它,那么只有当你的公共仓库的公共仓库保持不变时, 才会改变原来的HEADorigin / HEAD是代表远程仓库中HEAD本地副本的本地ref。 (它的全名是refs / remotes / origin / HEAD。)

我想上面的答案是你真正想知道的,但是要继续回答你明确提出的问题。当你克隆一个仓库时,origin / HEAD被自动设置,这就是它。 奇怪的是,它不是由像git remote update命令设置 – 我相信它将改变的唯一方法是如果你手动改变它。 (通过更改我的意思是指向一个不同的分支;显然,如果该分支更改,则指向更改的提交,这可能发生在提取/拉出/远程更新上。


编辑 :下面讨论的问题在Git 1.8.4.3中得到纠正; 看到这个更新 。


虽然有一个小小的警告。 HEAD是一个符号引用,指向一个分支,而不是直接提交,但是git远程传输协议只报告提交的提交。 所以Git知道HEAD指向的所有提交的SHA1, 那么它必须通过find指向相同提交的分支来推断HEAD的值。 这意味着,如果两个分支碰巧指向那里,这是不明确的。 (我相信如果可能的话,select高手,然后按字母顺序回到第一位)。你会在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 

奇怪的是,虽然这种方式打印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) 

所以,即使远程显示知道HEAD是主,它不会更新任何东西。 陈旧的foo分支被正确修剪,HEAD变成悬挂(指向一个不存在的分支),但它仍然不会更新它指向主。 如果你想解决这个问题,可以使用git remote set-head origin -a来自动确定原点的HEAD,然后设置origin / HEAD指向相应的远程分支。

这是您作为您当地回购的所有者的设置。 像这样改变它:

 git remote set-head origin some_branch 

而HEAD / HEAD将指向你的分支,而不是主人。 这将只适用于您的回购,而不适用于其他人。 默认情况下,它将指向master,除非在远程repo上configuration了其他内容。

手动input远程设置头提供了一些关于这方面的很好的信息。

编辑:强调:没有你告诉它,“移动”的唯一方法就是像重命名主分支 ,我不认为这是“有机”的情况。 所以,我会有机地说它不动。

什么原点/ HEAD“有机地”移动?

  • git clone设置它一次头部的起源点
    • 它作为git clone克隆克隆后的默认分支

HEAD在起源上代表什么?

  • 在裸仓库(通常在服务器上的仓库),它作为默认分支的标记,因为git clone以这种方式使用它
  • 在非裸存储库(本地或远程)上,它反映了存储库的当前结帐

什么来源/头?

  • git clone获取并设置它
  • 这是有道理的,如果git fetch更新像任何其他引用,但它不
  • git remote set-head origin -a读取并设置它
    • 有助于更新远程认为“默认分支”的本地知识

琐事

  • origin/HEAD也可以设置为任何其他值,而无需联系远程: git remote set-head origin <branch>
    • 除了testing,我没有看到这个用例
  • 不幸的是,遥控器上无法设置HEAD
  • 老版本的git不知道哪个分支HEAD指向远程,只有它提交的散列最终有:所以它只是希望select一个分支名称指向相同的散列

请记住,我们正在讨论两个独立的git回购。 您的代码和远程运行在其他地方的本地回购。

你是对的,当你改变一个分支时,HEAD指向你当前的分支。 所有这些都发生在你本地的git仓库上。 不是远程仓库,可以由其他开发人员拥有,也可以位于办公室的服务器,github或文件系统上的其他目录等等。

您的计算机(本地回购)没有业务更改远程git回购上的头指针。 例如,它可以由不同的开发者拥有。

还有一件事,你的计算机调用origin / XXX是你的计算机了解最后一次获取时的远程状态。

那么“有机地”更新origin / HEAD是什么? 这将是远程git回购活动。 不是你当地的回购。

人们提到

git symbolic-ref HEAD refs / head / my_other_branch

通常情况下,当服务器上有一个共享的中央git仓库供开发团队使用时,就可以使用它。 这将是一个在远程计算机上执行的命令。 你会看到这是远程git仓库的活动。

免责声明 :这是对Jefromi的答案的更新,我正在写这个答案 ,以保存好奇的一些时间。

我妄图复制(在Git 2.0.1中) remote HEAD is ambiguous Jeutti在他的回答中提到的remote HEAD is ambiguous消息; 所以我做了一些挖掘(通过克隆https://github.com/git/git并search日志)。; 它曾经是那个

 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 ,date为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 ,date为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问题。