はじめに
Gitは単なるファイル管理ツールではありません。
裏では、圧縮ファイル(Blob)、ツリーファイル(Tree)、**コミットファイル(Commit)**という特別なデータ構造を駆使して、ファイルのバージョンを効率よく管理しています。
この記事では、Gitの内部データ管理の仕組みを、初心者にもわかりやすく丁寧に解説します。
Gitのデータ保存場所
Gitでバージョン管理を開始すると、プロジェクト内に .git
という隠しディレクトリが作られます。
その中でもデータ管理の中枢となるのが、.git/objects/
というディレクトリです。
your-project/
└── .git/
├── objects/ # ← Gitオブジェクト(保存データ)
├── refs/
├── HEAD
└── その他設定ファイル
ここに、Gitが作成する3種類のオブジェクト、
- 圧縮ファイル(Blob)
- ツリーファイル(Tree)
- コミットファイル(Commit)
が保存されています。
Gitオブジェクトの3種類と役割
1. 圧縮ファイル(Blobオブジェクト)
ファイルの中身をそのまま記録するオブジェクトです。
-
作成タイミング:
git add
を実行したとき - 保存内容: ファイルの中身だけ(ファイル名やパスは持たない)
- ファイル名: ファイルの中身を元に計算されたSHA-1ハッシュ値
特徴
- 内容が同じであれば、ファイル名が違っても同じハッシュ値になり、一度だけ保存されます。
-
git add
をしても、同じ中身なら新たなBlobオブジェクトは作成されません。
イメージ
[hello.txt] → "hello world" → ハッシュ計算 → Blobオブジェクト作成
確認コマンド例
# ステージング時にBlobが作られる
git add hello.txt
# インデックス内Blob確認
git ls-files --stage
# Blobオブジェクトの中身を確認
git cat-file -p <ハッシュ値>
2. ツリーファイル(Treeオブジェクト)
ディレクトリ構造やファイル名を記録するオブジェクトです。
-
作成タイミング:
git commit
を実行したとき -
保存内容:
- ファイル名
- パーミッション
- 対応するBlobやTreeへのリンク情報
特徴
- プロジェクト全体のファイル構成を表現します。
- サブディレクトリを持つ場合は、Treeオブジェクト内にさらにTreeオブジェクトを参照します。
イメージ
ルートTree
├── hello.txt → Blobリンク
└── docs/ → サブTree
└── intro.md → Blobリンク
確認コマンド例
git commit -m "First commit"
# コミット後のTreeオブジェクト確認
git cat-file -p <Treeのハッシュ値>
3. コミットファイル(Commitオブジェクト)
履歴情報を管理するオブジェクトです。
-
作成タイミング:
git commit
を実行したとき -
保存内容:
- ルートTreeのハッシュ
- 親コミット(直前のコミット)のハッシュ
- 作者、コミッター、タイムスタンプ
- コミットメッセージ
特徴
- 親コミットを辿ることで、過去から現在までの履歴をたどることができます。
- これにより、Gitは「時間を巻き戻す」ことができます。
イメージ
[Commitオブジェクト]
├── Tree: <Treeハッシュ>
├── Parent: <親Commitハッシュ>(初回コミットの場合なし)
├── Author: あなた
├── Committer: あなた
└── Message: "最初のコミット"
確認コマンド例
# 最新のコミット情報を表示
git cat-file -p HEAD
Git内部でのデータ管理の流れ
ファイル編集からコミットまで、Git内部では次のような流れでオブジェクトが作成されています。
- ファイルを編集する
-
git add
を実行する
→ ファイルの内容(中身)をもとにBlobオブジェクトが作成される -
git commit
を実行する
→ ステージングエリアの状態からTreeオブジェクトを作成し、
→ さらにそのTreeを参照するCommitオブジェクトを作成する - ブランチのHEADが新しいCommitオブジェクトを指すように更新される
まとめ
オブジェクト | 作成タイミング | 役割 |
---|---|---|
Blob(圧縮ファイル) | git add |
ファイルの中身を保存 |
Tree(ツリーファイル) | git commit |
ファイル名・ディレクトリ構成を保存 |
Commit(コミットファイル) | git commit |
スナップショットと変更履歴を保存 |
これらのオブジェクトはすべて .git/objects/
に保存され、SHA-1ハッシュによって一意に管理されています。
これにより、Gitは高速かつ堅牢なバージョン管理を実現しています。