🗂️
Gitは内部的にどう動くのか?
Blob, Tree, Commit — Gitの3つのオブジェクト
『Gitは差分を保存する』は誤解だ。
実際は各コミットでファイル全体のスナップショットを保存している。ただし同じ内容のファイルは同じハッシュになるため重複しない。
3つのオブジェクト
Blob: ファイル内容。ファイル名ではなく内容のSHA-1で識別される。同じ内容は常に1つのblob。
Tree: ディレクトリ。ファイル名 → blobハッシュ、サブディレクトリ → treeハッシュのマッピング。
Commit: トップレベルtreeハッシュ + 親コミットハッシュ + 作者 + メッセージ。それだけ。
ブランチはただのポインタ
.git/refs/heads/mainはコミットハッシュ1行が書かれたテキストファイルだ。ブランチを作るのはファイルを1つ作るのと同じ。Gitのブランチが軽いと言われる理由。
HEADは『今どのブランチにいるか』を指すもう1つのポインタだ。
動作フロー
1
`git add` → ファイル内容からblob生成(.git/objects/)
2
`git commit` → indexからtree生成、tree + 親 + メッセージでcommit生成
3
ブランチポインタ(.git/refs/heads/xxx)を新コミットハッシュに更新
4
`git log`はHEAD → commit → parent → parent...のチェーンを遡る
5
`git cat-file -p <hash>`で任意のオブジェクトを直接確認できる
ユースケース
Gitコマンドの挙動を本質的に理解する
破損リポジトリの復旧(reflog、fsck)
カスタムツールの作成(libgit2、rugged)