GitのHEADとは何ですか?


1026

次のようなことを言っているGitのドキュメントを見る

ブランチはHEADで完全にマージする必要があります。

しかし、GitとはHEAD正確には何ですか?



回答:


775

HEADは「現在のブランチ」と考えることができます。でブランチを切り替えるとgit checkout、HEADリビジョンは新しいブランチの先端を指すように変更されます。

HEADが何を指しているかを確認するには、次のようにします。

cat .git/HEAD

私の場合、出力は次のとおりです。

$ cat .git/HEAD
ref: refs/heads/master

HEADは、ブランチ名に関連付けられていない特定のリビジョンを参照することができます。この状況は、切り離されたHEADと呼ばれます。


53
したがって、git HEADは、あなたがいるブランチに依存するコンテキストですよね?さらに、あなたは開発者ですか?たぶん、Git HEADはリポジトリ全体のグローバルなものになるのでしょうか、それとも各開発者の個人的なものになるのでしょうか。
bobobobo 2010

91
@bobobobo:そうです、HEADは現在のブランチを指すポインターのようなものです。別のブランチをチェックアウトすると、HEADは新しいブランチを指すように変更されます。現在のHEADは各リポジトリにローカルであるため、開発者ごとに異なります。
グレッグヒューギル2010

16
@Mengこれは私を助けました、それが役に立てば幸いです:marklodato.github.com/visual-git-guide/index-en.html
raphael

54
@動静的能量:HEADは任意のコミットを指すことができ、ブランチの最後のコミットである必要はありません。(HEADがブランチの最後のコミットではないコミットを指す場合、それは「デタッチされたHEAD」です)。
グレッグ・ヒューギル2012

127
HEADは「現在のブランチ」ではありません。Isは、作業ツリーの現在の状態が初期化されたコミットに付けられた名前です。より実際的には、チェックアウトされたコミットへのシンボリックな参照と考えることができます。
ベンコリンズ

184

他の人を引用するには

ヘッドは単にコミットオブジェクトへの参照です。各ヘッドには名前(ブランチ名やタグ名など)があります。デフォルトでは、マスターと呼ばれるすべてのリポジトリにヘッドがあります。リポジトリには、任意の数のヘッドを含めることができます。常に、1つのヘッドが「現在のヘッド」として選択されます。このヘッドは常に大文字でHEADにエイリアスされています。」

この違いに注意してください。「ヘッド」(小文字)は、リポジトリ内の名前付きヘッドのいずれかを指します。「HEAD」(大文字)は、現在アクティブなヘッドのみを指します。この区別は、Gitのドキュメントで頻繁に使用されます。

gitの内部動作をすばやくカバーする別の優れたソース(そして、ヘッド/ヘッドの理解を深める)は、こちらにあります。参照(ref :)またはヘッドまたはブランチは、コミット履歴のコミットに貼り付けられた付箋のようなものと考えることができます。通常、彼らはコミット一連の先端を指すが、彼らは周りに移動することができgit checkoutたりgit resetなど


これから:「それぞれの頭には名前があります」。そして「一つの頭が「現在の頭」として選ばれる。このヘッドはHEADのエイリアスです。」したがって、「HEAD」は「切り離されたHEAD」状態の状態を指しているわけではないと結論付けます。
gxyd

1
@gxyd HEADが「ヘッド」を指していない場合は、デタッチされたHEADです。これはgit checkout HEAD~2、既知のヘッドのコミットIDではない、たとえばを使用して指定したコミットのコミットIDを指しています。より完全な説明については、eagain.net / articles / git- for -computer-scientistsの記事を参照してください。
Silfheed 2016年

1
@Silfheed:一般的に、この答えは概念的には受け入れられた答えよりも適切だと思います(ブランチを指すために小文字の「頭」を使用すると、多くの人を混乱させますが)。ただしgit revertgit revert新しいコミットを作成し、現在のブランチを(新しい)チップのままにするだけなので、ブランチをチップに移動しない良い例ではありません。
LarsH

1
「これは既知のヘッドのコミットIDではありません」-実際には、切り離されたHEAD は、既知のヘッド(または複数のヘッド)のコミットIDでもあるコミットIDを指している可能性があります。切り離されているのは、HEADがヘッドではなくコミットIDを直接指していることです。これは将来の、などcommitの動作に影響しますreset
LarsH

1
@LarsH:参照ではなくコミットIDを指すデタッチされたHEADの良い点。これを実際に確認するには、.git / HEADを確認します。デタッチされている場合、既知のヘッドと同じコミットであっても、コミットのハッシュが含まれます。アタッチされている場合は、ヘッドへのパスが含まれます(つまり、「ref:refs / heads / bob」)。元に戻すコマンドに関しては、8年後、私はそのタイプミスを理解できませんでした。Gitリセットは、特定のコミットを指すように特定のヘッドを調整できるようにするものです。
Silfheed

62

github開発者のスコットチャコンによるこの定義をお勧めします[ ビデオ参照 ]:

ヘッドはあなたの現在のブランチです。これはシンボリックリファレンスです。ブランチへの参照です。あなたは常にHEADを持っていますが、HEADはこれらの他のポインターの1つを指していて、現在のブランチの1つを指しています。次のコミットの親です。これは、作業ディレクトリに最後にチェックアウトされたものでなければなりません...これは、作業ディレクトリが最後に確認された状態です。

ビデオ全体でgitシステム全体を公平に紹介しますので、時間があれば、すべてをご覧になることもお勧めします。


34
真DEFがあるので、「あなたの次のコミットの親」
ニコラス

1
また、「移動する次の分岐を指すもの」
ニコラス2013年

@nicolas- それは本当ではないと思います。HEADは任意のコミットを指すことができますが、必ずしもブランチを指す必要はありません。そうでない場合、「デタッチされたHEAD」モードになります。
スキューボ2013年

23
ビデオは素晴らしいですが、残念ながら、Stack Overflowには不適切な答えになります。ビデオが将来削除されるとどうなりますか?次に、あなたのリンクは何も指さないでしょう。より良い答えは、スコットがビデオで言ったことの筆記録を含むでしょう。

2
スコットは、ヘッドはブランチへのポインタであると言います。しかし、HEADは古いコミットも指すことができます。これは非常に混乱しています。
フィクシー:2014年

60

HEADは、現在使用しているローカルブランチを指す特別なポインターです。

プロGitのブック、章3.1 Gitのブランチ-一言で支店セクションで、新しいブランチを作成します

新しいブランチを作成するとどうなりますか?そうすると、移動するための新しいポインタが作成されます。たとえば、testingという新しいブランチを作成するとします。これを行うには、git branchコマンドを使用します。

$ git branch testing 

これにより、現在行っているのと同じコミットで新しいポインタが作成されます

ここに画像の説明を入力してください

Gitは現在どのブランチにいるかをどのようにして知るのですか?HEADと呼ばれる特別なポインタを保持します。これは、SubversionやCVSなど、使い慣れた他のVCSのHEADの概念とは大きく異なることに注意してください。Gitでは、これは現在使用しているローカルブランチへのポインターです。この場合、あなたはまだマスターです。git branchコマンドは新しいブランチを作成しただけで、そのブランチには切り替わりませんでした。

ここに画像の説明を入力してください


4
ニース、取り外されたHEADケースを示す画像を使用できます
Don Hatch

@DonHatch、デタッチされたHEADの良い説明stackoverflow.com/a/35301963/1074179
Alexandr

3
いい答えだ。ブランチはラベル付けされたコミットに他なりません。新しいコミットを作成すると、このラベルは新しい新しいコミットに移動されます。ラベルのないコミットをチェックアウトすると、デタッチされたHEAD状態になります。つまり、HEADはブランチラベルのないコミットを指しています。34ac2上記の例でチェックアウトすると、HEADはそのコミットを指し、デタッチされたHEADと呼ばれます。この状態では、変更を加えて実験し、変更をコミットすることもできますが、別のブランチをチェックアウトすると、もちろん新しいブランチを作成しない限り、すべての変更が失われます。
sleepwalkerfx 2018

1
@sleepwalkerfxですが、ブランチラベルを持つコミットをチェックアウトできますが、HEADはブランチラベルを指しているのではなくブランチのコミットID
Marc

1
@sleepwalkerfxこの時点でセマンティクスについて話していると思います。あなたは正しいブランチラベルは特定のコミットへのテキストリファレンスです。ただし、コミットではありません。したがって、を実行してそのgit logようなものが得られた場合commit ad0265... HEAD -> foo ...fooブランチはcommit idへの参照であることを意味しad0265ます。テキスト参照のチェックアウトを行うことfooは、分離したヘッドではありません。コミットIDのチェックアウトを実行するad0265と、ヘッドが切り離されます。あなたが伝えていることの微妙なところが欠けているのかもしれません。このテキストの壁が、私がどこで失われたかを発見するのに役立つことを願っています。
マルク

40

オライリーGitの本、第二EDTION、P.69、で述べたように、それは、その後、「デタッチHEAD」と呼ばれる特殊なケースではないと仮定すると、HEAD意味:

HEAD常に現在のブランチの最新のコミットを指します。ブランチを変更するHEADと、新しいブランチの最新のコミットを参照するように更新されます。

そう

HEADある現在のブランチの「先端」

HEAD最新のコミットを参照するために使用したりHEAD~、ヒントの前のコミットとして使用したり、以前のコミットとして使用したりできることに注意してください。HEAD~~HEAD~2


27

これらの回答の多くには、微妙ではあるが重要な誤解があります。私はそれを明らかにするために私の答えを追加すると思いました。

なにHEAD

頭はあなたです

HEADコミット履歴のどこにいてもシンボリックリファレンスです。どこへ行っても、影のように何でもします。コミットするHEADと移動します。何かをチェックアウトすると、HEAD移動します。あなたが何をするにせよ、あなたがあなたのコミット履歴のどこか新しい場所に移動したなら、あなたもHEAD一緒に移動しました。1つの一般的な誤解に対処するには:自分から切り離すことはできませんHEAD。それは、切り離されたHEAD状態とは異なります。「いやいや、私は切り離されたHEAD状態です。HEADを失いました!」覚えておいてください、それはあなたの頭です。HEADはあなたです。あなたはヘッドから切り離されていません。あなたとあなたのヘッドは別のものから切り離されています。

HEADは何に接続できますか?

HEADはい、コミットを指すことができますが、通常はそうではありません。もう一度言いましょう。通常HEAD、コミットを指しません。ブランチ参照を指します。これはそのブランチにアタッチされており、特定の操作(commitまたはなどreset)を実行すると、アタッチされたブランチはと一緒に移動しHEADます。フードの下を見ると、それが何を指しているのかを確認できます。

cat .git/HEAD

通常は次のようになります。

ref: refs/heads/master

時々あなたはこのようなものを得るでしょう:

a3c485d9688e3c6bc14b06ca1529f0e78edd3f86

これが、HEAD直接コミットを指す場合に起こります。これはHEAD、ブランチ参照以外のものを指しているため、デタッチされたHEADと呼ばれます。この状態でコミットすると、masterにアタッチされなくなったはHEAD、一緒に移動しなくなります。そのコミットがどこにあるかは問題ではありません。マスターブランチと同じコミットである可能性がありますが、がブランチでHEADはなくコミットを指している場合、それは切り離され、新しいコミットはブランチ参照に関連付けられません。

次の演習を試すと、これをグラフィカルに見ることができます。gitリポジトリから、これを実行します。あなたは少し異なるものを取得しますが、それらのキービットはそこにあります。コミットを直接チェックアウトするときは、最初の出力(ここではa3c485d)から取得した短縮ハッシュを使用します。

git checkout master
git log --pretty=format:"%h:  %d" -1
# a3c485d:   (HEAD -> master)

git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h:  %d" -1   
# a3c485d:   (HEAD, master)

OK、そのため、ここでは出力に小さな違いがあります。(ブランチではなく)コミットを直接チェックアウトすると、矢印ではなくコンマが表示されます。あなたはどう思いますか、私たちは切り離されたHEAD状態ですか?HEADはまだブランチ名に関連付けられている特定のリビジョンを参照しています。我々はまだだ上で、我々は、masterブランチされていませんか?

今試してください:

git status
# HEAD detached at a3c485d

いいえ。私たちは「切り離されたヘッド」状態にあります。

あなたは、同じ表現を見ることができます(HEAD -> branch)対を(HEAD, branch)git log -1

結論として

HEADあなたです。どこにいても、チェックアウトしたものを指します。通常、これはコミットではなく、ブランチです。HEAD コミット(またはタグ)を指している場合、ブランチも指すコミット(またはタグ)と同じであっても、あなた(およびHEAD)はそのブランチから切り離されています。ブランチがアタッチされていないので、新しいコミットを行うときにブランチはあなたに付いていきません。HEADただし、します。


1
ドキュメントが真実を記述している一方で、ソフトウェアは真実を定義しているので、私はこの答えが好きです。.git/HEADソフトウェアがHEADと見なすものです。
Don Branson、

2
概念的な定義だけで、これは受け入れられる答えになるはずです。
ata

22

HEAD作業コピーが指している現在のコミット、つまり現在チェックアウトしているコミットを指します。Gitリビジョンの指定に関する公式のLinuxカーネルドキュメントから:

HEAD 作業ツリーでの変更のベースとなったコミットに名前を付けます。

ただし、Gitの寄稿者であるJunio C Hamanoが彼のGit Blameブログで指摘しているように、Gitの次のバージョン1.8.4では@、の省略形としても使用できることに注意してくださいHEAD

「HEAD」と入力する代わりに、「git log @」など、代わりに「@」と発声できます。

Stack OverflowのユーザーVonC は、別の質問への回答で速記として選ばれた理由に関する興味深い情報@も見つけました。

また、一部の環境ではHEAD、特に大文字と小文字を区別しないファイルシステムを使用するオペレーティングシステム、特にWindowsとOS Xでは、大文字にする必要がない場合もあります。


17

ブランチの作成と操作を見てください

HEADは実際にはHEAD変数が参照する場所を決定する内容を持つファイルです。

$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed

このリポジトリでは、HEADファイルのコンテンツはrefs / heads / masterという名前の2番目のファイルを参照します。ファイルrefs / heads / masterには、masterブランチでの最新のコミットのハッシュが含まれています。

その結果、HEADは.git / refs / heads / masterファイルからのマスターブランチコミットを指します。

ここに画像の説明を入力してください


1
注意:gitguys.comリンクは、パークされたドメインを指しているようです。
MKesper 2018

14

グレッグ・ヒューギルの認められた答えのいくつかを詳しく述べたいと思います。Git Pocket Guideによると

ブランチ:

ブランチ自体は、名前付きコミット(ブランチの「ヒント」)からコミットグラフで到達可能なすべてのポイントとして定義されます。

HEAD:特別なタイプの参照

特別なリファレンスであるHEADは、どのブランチにいるかを決定します...

参照

Gitは2種類の参照、つまり「参照」と呼ばれる名前付きポインターを定義します。

  • オブジェクトID(通常はコミットまたはタグ)を直接指す単純な参照
  • シンボリック参照(またはsymref)、別の参照(単純またはシンボリック)を指す

Gregが述べたように、HEADは「切り離された状態」になる可能性があります。したがって、HEADは単純な参照(分離されたHEADの場合)またはsymrefのいずれかになります。

HEADが既存のブランチのシンボリック参照である場合、そのブランチは「オン」です。一方、HEADがSHA-1 IDで直接コミットに名前を付ける単純な参照の場合、ブランチは「オン」ではなく、「切り離されたHEAD」モードです。調査することを約束します。


@mikeありがとうございます!これは、以前のコミットをチェックアウトしたときに何が起こるかを明確にする最初の回答です。gitウェブサイトのを見て、「デタッチドヘッド」は、奇妙なリベースを行う場合にのみ遭遇する病的な状態であるという印象を受けました。しかし、以前のコミットをチェックアウトすることは奇妙なことではなく、そうするとき、HEADは「現在のブランチの先端」ではありません。ですから、実際に理解したのは初めてです。
Nat Kuhn

7

「HEAD」は現在のチェックアウトコミットだと思います。つまり、「HEAD」は現在チェックアウトされているコミットを指します。

クローンを作成してチェックアウトしていない場合、それが何を指しているのかわかりません。おそらく無効な場所です。


はい、特別な参照HEADは、現在チェックアウトしているコミットです。詳細はマニュアルを参照してください(関連する段落は図3.4の直後に続きます)。
カリオン2012年

1
リポジトリのクローンを作成すると、gitはデフォルトでmasterブランチをチェックアウトするため、HEADはマスターをポイントします。
sleske 2013

1
@sleske特別なオプションなしでリポジトリを複製すると、gitはリモートヘッドをチェックアウトします。通常masterはですが、常にそうとは限りません。参照remote set-head
De Novo

以前のコメントは正しかったremote set-headが、ローカルのデフォルトブランチにのみ影響し、サーバーのデフォルトは変更されません。
デ・ノボ

5

ヘッドは現在チェックアウトされているブランチの先端を指します。

ここに画像の説明を入力してください

リポジトリには.gitフォルダーがあります。次の場所にあるファイルを開きます:.git \ refs \ heads。そのファイル(ほとんどの場合はマスター)の(sha-1ハッシュ)コードは、最新のコミット、つまりコマンドの出力に表示されるものになりgit logます。.gitフォルダーの詳細:http : //gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html


1
現在のブランチの先端が最新のコミットを指しているというのはよくある誤解です。通常、それは本当ですが、も珍しくなくgit reset HEAD^、最新のコミット(以前のヒント)がブランチのヒントによってポイントされなくなりました。
LarsH

4

正解でgit reflog HEAD得られた要点を理解するための優れた方法は、を実行する ことです。HEADが指摘したすべての場所の履歴を取得できます。


4

以前のすべての回答を読んだ後、私はさらに明確にすることを望みました。公式のgit Webサイトhttp://git-scm.com/blogにあるこのブログは、私が探していたものを与えてくれました:

HEAD:最後のコミットスナップショット、次の親へのポインター

GitのHEADは、現在のブランチ参照へのポインタであり、現在のブランチ参照は、最後に行ったコミットまたは作業ディレクトリにチェックアウトされた最後のコミットへのポインターです。これはまた、次のコミットの親になることも意味します。HEADは最後のコミットのスナップショットであるため、一般的に考えると最も簡単です。


1
ヘッド:最後のコミットのスナップショット、次の親は正確ではありません。HEADコミットではありません。それ 1つを指します。
jub0bs 2014

皮肉の必要はありません。編集前は、引用は正確でしたが、太字の大きな文字は簡略化されており、少し誤解を招くものでした。今、それはより良いです。
jub0bs 2014

1
次の行を読んだ場合:GitのHEADは、現在のブランチ参照へのポインターです。これは、最後に行ったコミットまたは作業ディレクトリにチェックアウトされた最後のコミットへのポインターです。-「ポインタ」という単語の使用に注意してください。
user3751385 2014

「最後のコミットスナップショット」の説明は、HEADが通常どのように使用されることになっているのかを概念的に示していますが、実際には正確ではありません。コミットを行ってから別のブランチに切り替えると、HEADは最後のコミットスナップショットをポイントしなくなります。先ほど切り替えたブランチの最後のコミットスナップショットを指します。Iの場合checkout HEAD^、HEADはどのブランチの最後のコミットスナップショットも指しません。
LarsH

「次のコミットの親(今すぐコミットする場合)」の方が正確ですが、gitにはコミット以外にもHEADの影響を受ける多くの操作があります。本当に、最後に、HEADはHEADであり、その性質は、それがのようなコマンドにどのように影響するかによって定義されcommitmergerebaselog、などしかし、概念的には、多分「(ポインタ)が現在の位置が」良い要約です。
LarsH

3

それはHEADあなたがチェックアウトした最後のコミットの単なるタグのように感じます。

これは、特定のブランチの先端(「マスター」など)またはブランチの中間のコミット(「切り離されたヘッド」)の場合があります。


1

すべての定義に加えて、私の心に残ったのは、コミットを行うと、GITがリポジトリ内にコミットオブジェクトを作成することでした。コミットオブジェクトには親(またはマージコミットの場合は複数の親)が必要です。では、gitは現在のコミットの親をどのようにして知るのでしょうか。したがって、HEADは、現在のコミットの親になる最後のコミット(の参照)へのポインタです。


0

これらの2つはあなたを混乱させるかもしれません:

最近提出されたブランチの名前付き参照を指します。パッケージ参照を使用しない限り、ヘッドは通常$ GIT_DIR / refs / heads /に保存されます。

現在のブランチ、または作業ツリーは通常、HEADが指しているツリーから生成されます。分離したHEADを使用している場合を除き、HEADはヘッドを指す必要があります。


0

見てくださいhttp://git-scm.com/book/en/Git-Branching-What-a-Branch-Isを

図3-5。現在のブランチを指すHEADファイル。


4
Stackoverflowではリンクのみの回答は一般的に嫌われます。回答に関連情報をインラインで入力してください。
HaskellElephant 2012年

2
これは完全に正しいわけではありません。何をHEAD参照するかは、ベアリポジトリと非ベアリポジトリのどちらについて話しているのかによって異なります。非ベアリポジトリのコンテキストでは、現在チェックアウトされているコミットを効果的に参照します。これには、ブランチがアタッチされている必要はありません(つまり、切り離されたHEAD状態の場合)。

0

ブランチは、実際のようなコミットIDを保持するポインタである17a5HEADは、ユーザーが現在作業しているブランチへのポインタです。

HEADには、次のような参照ファイルがあります。

ref:

これらのファイルにアクセスする.git/HEAD .git/refsには、作業中のリポジトリにあるファイルにアクセス します。


0

Gitコミットについてのすべてです。
そしてHead、現在チェックアウトしているコミットを指します。

$ git cat-file -t HEAD
commit

ブランチをチェックアウトすると、HEADはそのブランチの最新のコミットを指します。HEADの内容は、以下のように確認できます(マスターブランチの場合)。

$ cat .git/refs/heads/master
  b089141cc8a7d89d606b2f7c15bfdc48640a8e25

-5

概念として、ヘッドはブランチの最新リビジョンです。名前付きブランチごとに複数のヘッドがある場合、マージせずにローカルコミットを実行するときにおそらくそれを作成し、事実上名前なしブランチを作成しました。

「クリーンな」リポジトリを作成するには、名前付きブランチごとに1つのヘッドがあり、ローカルで作業した後は常に名前付きブランチにマージする必要があります。

これはMercurialにも当てはまります。


4
これはMercurialには当てはまりますが、Gitには当てはまりません
モニカの復活-notmaynard 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.