Dev Study
← Gitの内部構造から理解する コース

11. detached HEAD と「消えたコミット」— 参照されないだけで残っている

新卒が最も慌てるのが「detached HEAD」の警告と、コミットが消えたように見える場面です。ここも参照の構造で説明がつきますし、多くの場合コミットは消えていません。

① detached HEAD は HEAD がブランチを経由していない状態

通常時と detached の違い
通常: HEAD → refs/heads/main → commit二段の参照
detached: HEAD → commitブランチを飛ばして直接指す
  • ・git checkout <コミットハッシュ> でこの状態になる
  • ・この状態でコミットすると、更新されるブランチファイルが存在しない
  • ・つまり、そのコミットを指す名前がどこにもない状態になる

危険なのはコミットが壊れることではなく、「名前がついていないので見失いやすい」ことです。git switch -c <名前> でその場に名前を付ければ解決します。

② 参照されなくなったコミットも残っている

オブジェクトDBとrefsは別物
オブジェクトDBcommit E は消えずに残っている
refsどのブランチもEを指していない
git reflog で HEAD が過去に指した先を調べられる
Eのハッシュを見つけて名前を付け直せるgit branch <名前> <ハッシュ>
  • ・reflog は HEAD やブランチが指した先の履歴をローカルに記録している
  • ・参照されないオブジェクトは、しばらく経って git gc が走るまで残る
  • ・「コミットが消えた」の多くは「名前を失っただけ」

オブジェクトは中身から名前が決まる不変のデータで、refsはそこを指す付箋です。付箋を剥がしても中身は残っています。落ち着いて reflog を見てください。

サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗