origin / HEADはどのように設定されますか?


144

元の参照を追跡するためにブランチを設定しています。 git checkout <branchname>はそのブランチに切り替わり、a git statusはブランチからの距離が原点からどれだけ離れているかを示しますが、origin/HEADそれでもまだを指していてorigin/masterorigin/<branchname>

だから私の質問は、どのような状況でorigin / HEADが移動するのですか?

編集:

origin / HEADを移動する方法についての回答に感謝しますが、「オーガニックに」それを移動する方法に興味があります。それ以外に、明示的にそうするように指示します。

たとえば、ブランチを切り替えると、gitはHEADをチェックアウトしているブランチに向けるので、origin / HEADが同じように移動しないことに驚いています。


この質問は、などのリモート上のローカルシンボリック参照に関するものであることに注意してくださいrefs/origin/HEAD。リポジトリ自体のシンボリック参照HEADがどのように設定されるかについてではありません。
2017年

回答:


173

最初に、あなたの質問が少し誤解を示していることに注意してください。origin / HEADは、リモートのデフォルトブランチを表します。つまり、オリジンを呼び出しているリモートリポジトリにあるHEADです。リポジトリのブランチを切り替えても、影響はありません。リモートブランチについても同様です。あなたが持っているかもしれないmasterorigin/master、あなたのレポ、中origin/masterのローカルコピーを表すmasterリモートリポジトリにブランチを。

originのHEADは、あなたまたは誰かがリモートリポジトリで実際に変更した場合にのみ変更されます。これは基本的には発生しません。安定したブランチ(おそらくマスター)で、デフォルトのブランチとパブリックリポジトリを一定に保ちます。origin / HEADは、リモートリポジトリ内のHEADのローカルコピーを表すローカル参照です。(そのフルネームはrefs / remotes / origin / HEADです。)

上記はあなたが実際に知りたかったことの答えだと思いますが、先に進んで明示的に尋ねた質問に答えます... origin / HEADは、リポジトリのクローンを作成するときに自動的に設定されます。奇妙なことに、次のようなコマンドで設定されないgit remote update -手動で変更した場合にのみ変更されると思います。(変更とは、別のブランチを指すことを意味します。そのブランチが変更されると、コミットが変更を指すことを意味します。これは、フェッチ/プル/リモート更新で発生する可能性があります。)


編集:以下で説明する問題はGit 1.8.4.3で修正されましたこのアップデートをご覧ください。


ただし、小さな注意事項があります。HEADはシンボリック参照であり、直接コミットを指すのではなくブランチを指しますが、gitリモート転送プロトコルは参照のコミットのみを報告します。したがって、GitはHEADと他のすべての参照によって指されたコミットのSHA1を知っています。次に、同じコミットを指すブランチを見つけて、HEADの値を推定する必要があります。これは、2つのブランチが偶然そこを指している場合、あいまいであることを意味します。(私は、最初のアルファベット順にフォールバック、可能であればそれはマスターを選ぶと信じています。)あなたは、これはの出力で報告され表示されます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上記のようにoriginのHEADが自動的に決定され、実際にorigin / HEADが適切なリモートブランチを指すように設定されます。


@jefromi素晴らしい答え!単なる注釈:HEADは、コミットを直接指すのではなく、ブランチを指すシンボリック参照である[...]と書くが、完全性のためには、「切り離されたHEAD状態」について言及する価値があるかもしれない。
jub0bs 14

2
@Jubobsありがとう!私の回答を更新する必要がある場合は、自由に編集してください。2年前の事実と現在の事実を整理する必要がないため、実際にどのように機能するかについての簡単な要約を読む時間を確実に節約できます。 。
Cascabel 2014

これを少なくとも5回読んだが、それでも少しは理解していない
krb686

7
git remote set-head origin -a私のために仕事をした
Shujito

75

これは、ローカルリポジトリの所有者としての設定です。次のように変更します。

git remote set-head origin some_branch

そしてorigin / HEADはマスターではなくブランチを指します。これはあなたのリポジトリにのみ適用され、他のリポジトリには適用されません。デフォルトでは、リモートリポジトリで他に何かが構成されていない限り、マスターを指します。

リモートセットヘッドの手動入力は、これに関するいくつかの優れた情報を提供します。

編集:強調する:言わない限り、「移動」する唯一の方法は、マスターブランチの名前を変更するような場合です。つまり、有機的には動かないということです。


1
ここでは編集の強調は完全に正しくはありません。また、masterブランチ上にないローカルコピーからクローンを作成する場合にも変更できます。
2014年

私はクローンが「動いている」とは考えていませんが、それについては意見が
分かれる

24

origin / HEADを「有機的に」動かすものは何ですか?

  • git clone HEADが原点にある場所に一度設定します
    • これは、クローン作成後にチェックアウトするデフォルトのブランチとして機能します git clone

HEAD on originは何を表していますか?

  • 裸のリポジトリ(多くの場合、「サーバー上で」レポジトリ)、それは、デフォルトのブランチのためのマーカーとしての役割を果たす上の理由git cloneような方法で使用のこと
  • 非ベアリポジトリ(ローカルまたはリモート)では、リポジトリの現在のチェックアウトを反映します。

origin / HEADを設定するものは何ですか?

  • git clone それをフェッチして設定します
  • git fetch他の参照のように更新すると意味がありますが、そうではありません
  • git remote set-head origin -a それをフェッチして設定します
    • リモートが「デフォルトのブランチ」と見なすものに関するローカルの知識を更新するのに役立ちます

トリビア

  • origin/HEAD リモコンに接続せずに、他の値に設定することもできます。 git remote set-head origin <branch>
    • テストを除いて、これのユースケースはありません
  • 残念ながら、リモートでHEADを設定することはできません。
  • 古いバージョンのgitは、リモートのHEADが指すブランチを認識せず、最終的に持っているコミットハッシュのみを認識していました。そのため、同じハッシュを指すブランチ名を選択しただけです

私は参照を失いorigin/HEAD、あなたの解決策が助けになりました。ありがとう!
java_dude 2015

git fetch(ローカル)ショートカットを設定できるので、更新に同意しません。ドキュメントの引用:「リモートにデフォルトのブランチを用意する必要はありませんが、特定のブランチの代わりにリモートの名前を指定できます」。リモートの変更によってローカルに構成されたショートカットが更新されると、奇妙なことになります。
Micha Wiedenmann、

@MichaWiedenmannなぜローカルで構成されたショートカットになるのでしょうか?ローカルに構成されたショートカットのorigin/HEAD名前は不適切です。またgit clone、「ローカルに構成されたブランチ」のデフォルトとしてリモート名を使用すると、これも矛盾します。非ベアリポジトリでは、リモートのcurrentを使用しても意味がありませんHEAD
ロバートシーマー

10

免責事項:これはJefromiの回答の更新です。これは、好奇心をそそる時間を節約するために書いています。

remote HEAD is ambiguousJefromiが彼の回答で述べているメッセージを(Git 2.0.1で)複製しようとしても無駄でした。そこで、少し掘り下げました(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.

4229f1fa325870d6b24fe2a4c7d2ed5f14c6f7712009年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以降を使用している場合は、あいまいなリモートヘッドの問題に遭遇しないようにする必要があります。


1
gitソースのタグに基づいて、この修正はgitバージョン1.8.4.3以降に適用されます。
torek 2014

@RobertSiemerよくわかりませんが、そうだと思います。
jub0bs

8

私たちが話している2つの独立したgitリポジトリがあることに注意してください。コードを含むローカルリポジトリと別の場所で実行されるリモート。

あなたの言うとおり、ブランチを変更すると、HEADは現在のブランチを指します。これはすべて、ローカルのgitリポジトリで行われています。リモートリポジトリではありません。これは、別の開発者が所有したり、オフィスのサーバーやgithubに置いたり、ファイルシステムの別のディレクトリなどに置いたりすることはできません。

コンピューター(ローカルリポジトリ)では、リモートgitリポジトリのHEADポインターを変更する必要はありません。たとえば、別の開発者が所有している可能性があります。

もう1つ、コンピュータがorigin / XXXと呼ぶのは、最後のフェッチ時のリモートの状態についてのコンピュータの理解です。

それでは、「organic」にorigin / HEADをどのように更新しますか これは、リモートgitリポジトリでのアクティビティです。ローカルリポジトリではありません。

人々は言及しました

git symbolic-ref HEAD refs / head / my_other_branch

通常、これは、開発チームが使用する共有の中央gitリポジトリがサーバー上にある場合に使用されます。リモートコンピュータで実行されるコマンドになります。これは、リモートgitリポジトリのアクティビティとして表示されます。


1
申し訳ありませんが、少し繰り返しが多い場合。gitは分散バージョン管理システムであり、2つのリポジトリは独立しているという事実を指摘したいだけです。
パブロモーリン2012年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.