起源/ HEAD如何设置? [英] How does origin/HEAD get set?

查看:89
本文介绍了起源/ HEAD如何设置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分支设置为追踪原始参考。 git checkout< branchname> 切换到该分支,并且 git status 会显示我前后的距离分支来自原点,但我很惊讶 origin / HEAD 仍然指向 origin / master ,而不是 origin /< branchname>



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

编辑:



我很欣赏 移动原点/ HEAD的答案,但我感兴趣的是有机地移动它,除了我明确告诉它这样做。

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

解决方案

首先注意你的问题显示了一些误解。 origin / HEAD表示远程上的默认分支,即位于您正在呼叫的远程存储库中的HEAD。当您在回购中切换分支时,您不会影响到这一点。远程分支也是如此;你可能在你的仓库中有 master origin / master ,其中 origin / master 表示远程存储库中的 master 分支的本地副本。

如果您或其他人实际在远程存储库中进行了更改,那么origin的HEAD只会更改,这基本上不会发生 - 您希望默认在稳定的分支(可能是主人)上分支公共回购以保持不变。 origin / HEAD是代表远程存储库中HEAD本地副本的本地ref。(其全名是refs / remotes / origin / HEAD。)



我想上面的回答是你真正想知道的,但是要继续回答你明确提出的问题......克隆仓库时origin / HEAD会自动设置,这就是它。奇怪的是, 没有像 git remote update 这样的命令设置 - 我相信它会改变的唯一方法是如果你手动改变它。 (通过更改,我的意思是指向不同的分支;显然,如果分支更改,它会指向更改,这可能发生在fetch / pull / remote更新上。)




编辑:下面讨论的问题已在 Git 1.8.4.3 中解决。请参阅此更新






虽然有一个小小的警告。 HEAD是一个符号引用,指向一个分支,而不是直接提交,但是git远程传输协议只报告提交的提交。所以Git知道HEAD和所有其他文件指向的提交的SHA1;然后它必须通过找到指向相同提交的分支来推断HEAD的值。这意味着如果两个分支碰巧指向那里,它是不明确的。 (我相信如果可能的话,它会选择主人,然后回到第一个字母)。您会在 git remote show origin 的输出中看到这个报告:

  $ git远程显示来源
*远程来源
提取网址:...
推送网址:..
HEAD分支(远程HEAD不明确,可能是下列之一):
foo
master

奇怪的是,虽然这种方式打印HEAD的概念会改变,如果事情在远程更改(例如,如果foo被删除),它实际上并不会更新 refs /遥控器/原点/ HEAD 。这可能会导致非常奇怪的情况。说在上面的例子中,origin / HEAD实际上指向了foo,然后删除了origin的foo分支。我们可以这样做:

  $ git remote show origin 
...
HEAD分支:master
$ git symbolic-ref refs / remotes / origin / HEAD
refs / remotes / origin / foo
$ git remote update --prune origin
获取原点
x [删除](无) - >原产地/ foo
(refs / remotes / origin / HEAD已成为悬挂)

虽然远程节目知道HEAD是主人,但它不会更新任何东西。 stale foo分支被正确修剪,并且HEAD变成悬挂(指向不存在的分支),并且仍然不会将其更新为指向主。如果你想解决这个问题,可以使用 git remote set-head origin -a 来自动确定原点的HEAD,然后设置origin / HEAD指向适当的远程分支。


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>

So my question is, under what circumstances does origin/HEAD get moved?

EDIT:

I appreciate the answers about how to move origin/HEAD, but I'm interested in what "organically" moves it, outside of me explicitly telling it to do so.

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.

解决方案

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'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.)

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 not set 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.)


Edit: The problem discussed below was corrected in Git 1.8.4.3; see this update.


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:

$ 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:

$ 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 still doesn'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如何设置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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