このページで分かること
- Git が保存しているのは4種類のオブジェクトだけだと分かる
- blob・tree・commit・tag がそれぞれ何を持っているか説明できる
git cat-fileでオブジェクトの中身を開けて確かめられる- ID が中身から計算されることと、その意味が分かる
第3部の16で、コミットは「その時点の全体の写真」だと見ました。このページでは、その写真を分解します。.git の中に保存されているものは、突き詰めると4種類の部品しかありません。Git ではこの部品をオブジェクト(object)と呼びます。
4つのオブジェクトの関係
まず、フォルダの中にフォルダがある状態を作って記録します。
cd ~/git-practice
mkdir recipes
echo "卵 2個" > recipes/cake.txt
git add recipes
git commit -m "ケーキのレシピを追加"
このコミットを分解すると、次のような入れ子になっています。

外側から内側へ、「何を記録したか」から「ファイルの中身」へと細かくなります。
| オブジェクト | 持っているもの | 対応するもの |
|---|---|---|
| blob | ファイルの中身だけ | ファイル |
| tree | ファイル名・フォルダ名と、それぞれの中身のID | フォルダ |
| commit | いちばん上の tree のID、1つ前の commit のID、記録した人・日時・メッセージ | 1回の記録 |
| tag | 指す commit のID、名前、作った人・メッセージ | 記録に付けた目印 |
図は入れ子で描いていますが、実際には中に入っているのではなく、相手のIDを書いて指しているだけです。以下で1つずつ開けて確かめます。
オブジェクトを開ける:git cat-file
git cat-file は、オブジェクトの中身を表示するコマンドです。-t で種類を、-p で中身を表示します。
commit
git cat-file -t HEAD
# 出力:
# commit
git cat-file -p HEAD
# 出力:
# tree e61b7af4857312e4b55eaa25dd4c4e0cd7a03f2b
# parent 29c43994091deca933abfcfca9795596789675ee
# author Taro Yamada <[email protected]> 1792630800 +0900
# committer Taro Yamada <[email protected]> 1792630800 +0900
#
# ケーキのレシピを追加
commit が持っているのはこれだけです。ファイルの中身は1つも入っていません。 tree の行が「このときの全体の写真」を、parent の行が「1つ前の commit」を指しています。1792630800 は日時を秒数で表したものです。
補足
author は変更を作った人、committer は記録した人です。ふだんは同じ人になります。違うのは、他人の変更を受け取って記録する場合などです。
tree
git cat-file -p 'HEAD^{tree}'
# 出力:
# 100644 blob 64442fd642ae90b9c4be6583fa758d8b2e884f66 .gitignore
# 040000 tree 9687daeb9b93472bfcd466d61e6d8c3acef4e967 recipes
# 100644 blob a2a4dd6683d9012c00d693af6c5b1f02f225a091 shopping.txt
# 100644 blob d3038db570e4c542737f1ab3a559741e5af3628f todo.txt
HEAD^{tree} は「HEAD のコミットが指す tree」という指定です(シェルが記号を誤解しないよう、引用符で囲んでいます)。第3部の16の git ls-tree と同じ一覧で、recipes フォルダが tree として入っていることが分かります。先頭の 100644 は普通のファイル、040000 はフォルダを表す印です。
git cat-file -p HEAD:recipes
# 出力:
# 100644 blob c0fa007ec11499026d24c4028de6083e274444fc cake.txt
HEAD:recipes は「HEAD のコミットの recipes」という指定です。フォルダの中のフォルダは、tree の中の tree になっています。
blob
git cat-file -p HEAD:shopping.txt
# 出力:
# 豆乳を買う
# 卵を買う
# パンを買う
blob はファイルの中身そのものです。ファイル名はどこにも書かれていません。 名前は tree が持っています。だから第2部の13で名前を変えたとき、中身の blob はそのままで、tree の中の名前だけが変わりました。
ID は中身から計算される
ここまでに出てきた長い英数字は、すべてオブジェクトのハッシュ(ID)です。Git は、オブジェクトの中身から SHA-1 という計算方法で40桁の値を求め、それを ID にしています。
中身が同じなら、誰がいつ計算しても同じ値になります。試しに、第2部の08で最初に作った memo.txt と同じ中身から ID を計算してみます。
echo "牛乳を買う" | git hash-object --stdin
# 出力:
# 4d4d7608c63e573f12c7f6bb19bf03345608a004
git cat-file -p 4d4d760
# 出力:
# 牛乳を買う
git hash-object は「この中身なら、ID はいくつになるか」を計算するだけのコマンドです。出てきた ID を git cat-file に渡すと、第2部の08で記録した中身が出てきます。手元でも同じ 4d4d760… になるはずです。
ここから、Git の性質がいくつも説明できます。
- 同じ中身は1つしか保存されない(第3部の16):ID が同じなら同じオブジェクトだから
- 記録が壊れると気づける:中身が1文字でも変われば ID が合わなくなる
- commit の ID は手元ごとに違う:commit の中身には記録した人と日時が入っているから
補足
将来の Git 3.0 では、新しく作るリポジトリの計算方法が、より安全な SHA-256(64桁)に変わる予定です。考え方は同じで、桁数が増えるだけです(出典:Git の BreakingChanges)。
保存場所
オブジェクトは、.git/objects の中に、ID の先頭2文字のフォルダと残り38文字のファイル名で保存されます。
ls .git/objects/a2/
# 出力:
# a4dd6683d9012c00d693af6c5b1f02f225a091
shopping.txt の blob a2a4dd6… です。中身は圧縮されているので、cat で開いても読めません。読むときは git cat-file を使います。
tag:記録に付ける目印
4つ目の tag は、特定のコミットに名前を付けて目印にするオブジェクトです。
git tag -a v1.0 -m "最初の区切り"
git cat-file -p v1.0
# 出力:
# object b505e8e8f92abb8142a6ca486600de9100f98e42
# type commit
# tag v1.0
# tagger Taro Yamada <[email protected]> 1792630800 +0900
#
# 最初の区切り
object の行が、目印を付けた commit を指しています。タグの使い方は第5部の30で扱います。
矢印の向きについて
commit は parent で1つ前の commit を指しています。つまり、記録の上では新しいものが古いものを指す、時間と逆向きのつながりです。新しい commit を作るとき、Git が知っているのは「今の commit」だけなので、新しいほうに「親はこれ」と書くしかないためです。
このガイドの図では、コミットを左が古く右が新しい順に並べ、親を指す矢印はあえて描いていません。矢印を描くと、時間の流れと逆向きに読んでしまいやすいためです。図の線は「このコミットの次がこれ」という並びだけを表している、と読んでください。
よくある疑問
Q. 空のフォルダが記録できないのはなぜですか?
A. tree は「中にあるファイルとフォルダの一覧」なので、中身が空だと tree として書く内容がないからです。第2部の12で触れた .gitkeep は、この仕組みに合わせた工夫です。
まとめ
- Git が保存しているのは blob・tree・commit・tag の4種類のオブジェクトだけ
- blob はファイルの中身だけ、tree はファイル名と中身のIDの一覧を持つ
- commit はいちばん上の tree と1つ前の commit を指し、記録した人・日時・メッセージを持つ
- ID は中身から計算されるので、同じ中身は同じ ID になる
- commit は1つ前の commit を指している。このガイドの図では、時間の流れに合わせて左から右に並べる
次のページ
18. HEAD とは何か・detached HEAD ── 第2部で何度も使った HEAD の正体と、「今どこにいるか」が分からなくなる状態を見ます。
この記事の最終確認日: 2026年10月