HEADってなんだ?
Gitの学習中、ちょいちょい出てくる HEAD というキーワード
例えばインデックスを取り消すときとか
$ git reset HEAD
リモートブランチにチェックアウトしたときとか
$ git checkout remotes/origin/main
Note: switching to 'remotes/origin/main'.
:省略
$ git status
HEAD detached at origin/main
nothing to commit, working tree clean
git reset HEADはインデックスを取り消せるので最新のコミットのようにも思えるがそれだと HEAD detached でコミットが切り離されてるのに、git log で最新のコミットが見えているのが説明つかない。
そこで調べてみた
HEADは現在自分がいるブランチを指すポインタ
そのままの意味なので、そんなの当たり前じゃんという方はこれ以上本記事を見ても学びはないと思います。お疲れさまでした。
上記見てもよくわからないよって方はもうしばらくお付き合いください。まず上記の意味を理解するためには、ブランチを理解する必要があります。
Gitを使い始めた方でもブランチの意味はなんとく理解できると思います。mainブランチを始め、同じプロジェクト内のファイルを同時進行で修正変更できるよう枝分かれさせたやつです。
ですが、実際のブランチは特定時点のコミットファイルを参照するポインタに過ぎません。ある時点のバージョンを記録したファイルがコミットファイルですよね?このコミットファイルを参照しているものがブランチです。以下を見てください
98ca9 → 34ac2 → f30ab という順にコミットファイルが作成されています。で、f30abをmasterブランチとtestingブランチが参照しています。このようにブランチはある時点のコミットファイルを参照しているに過ぎません。
で、話を戻すとHEADというのは、この図の通りブランチを参照するポインタです。正確には現在自分がいるブランチを指しています。なので HEADはブランチを通してコミットファイルの情報を参照できます。
これを理解すると冒頭の話も理解できます。
例えば git reset HEAD でインデックスの変更が取り消されるのは、インデックスの情報がHEADを通じてブランチの指すコミットと同じになる(= コミット後にステージングされた情報が消える)ためです。
以下の状態は、リモートブランチのコミットファイルにポインタが移動したけどローカルにブランチがないということを意味しています。
$ git checkout remotes/origin/main
Note: switching to 'remotes/origin/main'.
:省略
$ git status
HEAD detached at origin/main
nothing to commit, working tree clean
つまり HEADがブランチを介さず直接リモートリポジトリの指すコミットファイルを参照しています。なので、コミット履歴が見えるのです。
ちなみに余談ですが、git checkoutは多機能すぎるので、ブランチを移動する機能のみに分解された git switch というコマンドがあります。git switch でリモートブランチに直接移動しようとすると怒られて移動できません。
$ git switch remotes/origin/main
fatal: a branch is expected, got remote branch 'origin/main'
hint: If you want to detach HEAD at the commit, try again with the --detach option.
detach HEADの状態でswitchしたいなら --detach使えと言われてますね。このようにswitch コマンドでは、オプションなしでリモートブランチに移動することができなくなっています。ブランチなしでコミットを参照するのはよろしくないようです。
ということで、HEADは現在のブランチを参照するポインタだよという記事でした。ここを覚えておけば初学の段階でHEADに躓くことはないと思います。
以上、お疲れさまでした。