Gitのオブジェクトについて、図を使って分かりやすくまとめます。
この記事は以下のGit公式ドキュメントを参考にしています。
この記事の内容
Gitのオブジェクトとは?
Gitのオブジェクトとは、Gitが管理するファイルやコミットの情報を保存する時のデータ形式です。
Gitの各種コマンドは、ほとんどがこのオブジェクトを操作するために存在しています。
Gitのオブジェクトの構造を理解する事は、Gitそのものを理解する事につながります。
Gitはキー・バリューストア形式のデータベース

Gitのオブジェクトを語る前に、まずはGitがどのようにデータを格納しているのかを説明します。
Gitの内部構造を理解すると、オブジェクトの理解しやすくなります。
Gitはファイルやコミットの情報をキー・バリューストア形式のデータベースで管理しています。
キー・バリューストア形式とは、データを指し示す「キー」と、キーとペアになる「バリュー(値)」のみが定義されたシンプルなデータ保存形式です。
キー・バリューストアでは値の形式は定義せず、どんなデータでも扱えることが特徴です。
Gitではキー・バリューストアの「キー」の部分はオブジェクトのハッシュ値という値を使い、「バリュー」の部分がGitオブジェクトとなっています。

Gitではリポジトリで管理するファイルやコミットの情報をGitオブジェクトとして保存します。
例えばコミットのオブジェクトは一つ前のコミットオブジェクトのハッシュ値を持つ事でコミット履歴を形成します。
Gitのシステムはこのようなシンプルなデータ構造で成り立っています。
Gitオブジェクトを作る

git hash-object
コマンドを使ってGitオブジェクトを作成、保存する事ができます。
試してみましょう。任意のディレクトリでgit init
してから、git hash-object
を実行します。
# git init
# echo 'test' | git hash-object -w --stdin
9daeafb9864cf43055ae93beb0afd6c7d144bfa4
「test」という文字列をgit hash-object
コマンドに渡しています。--stdin
オプションで文字列を受け取り、-w
オプションでオブジェクトを保存します。git hash-object
コマンドは実行結果としてオブジェクトのキーとなる40桁のハッシュ値を出力します。
このハッシュ値は「test」というデータに対して常に「9daeafb9864cf43055ae93beb0afd6c7d144bfa4」
という値になります。
オブジェクトは.git/objects
ディレクトリの下に作られます。
# find .git/objects -type f
.git/objects/9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
ハッシュ値の最初の2文字がサブディレクトリ名、残りの38文字がファイル名として保存されています。
このファイルはバイナリデータになっているので、cat
などしても人間に分かる形では見れません。
# cat .git/objects/9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
xK��OR0e(I-.� ��
人間に分かる形で見るにはgit cat-file
コマンドを使います。
# git cat-file -p 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
test
「test」というデータが保存されている事が分かります。
ファイルをGitオブジェクトに保存する
ファイルをGitオブジェクトに保存するのもgit hash-object
コマンドを使います。
「virsion1」というデータが保存された「test.txt」というファイルを作り、gitオブジェクトとして保存します。
# echo 'version1' > test.txt
# git hash-object -w test.txt
5bdcfc19f119febc749eef9a9551bc335cb965e2
この時Gitオブジェクトにはファイル名は保存されず、「version1」というデータだけが保存されています。
保存されたオブジェクトを確認してみます。
# git cat-file -p 5bdcfc19f119febc749eef9a9551bc335cb965e2
version1
「version1」というデータが保存されている事が分かります。
さらに「test.txt」の内容を書き換えて新しいオブジェクトを保存してみます。
# echo 'version2' > test.txt
# git hash-object -w test.txt
df7af2c382e49245443687973ceb711b2b74cb4a
# git cat-file -p df7af2c382e49245443687973ceb711b2b74cb4a
version2
「virsion2」というデータが保存されたオブジェクトが作られました。
ファイルの内容が変わるとGitオブジェクトのハッシュ値が変わるので、ファイルが更新されると新しいGitオブジェクトが生成されます。

「test.txt」の内容は書き換わってしまいましたが、保存済みのGitオブジェクトを使って前のバージョンに戻すことができます。
# cat test.txt
version2
# git cat-file -p 5bdcfc19f119febc749eef9a9551bc335cb965e2 > test.txt
# cat test.txt
version1
最初に保存したGitオブジェクトを使って「version1」に戻すことができました。
実際にGitを使うときはこのような操作はしませんが、バージョン管理の原理としてはこれが基本となります。
Gitのオブジェクトの種類

ここでGitで扱われるオブジェクトの種類を確認しておきましょう。
Gitで扱われるオブジェクトは以下の4種類あります。
種類 | 概要 |
blob | ファイルの内容が保存される。 |
tree | ディレクトリの情報が保存される。 |
commit | コミットの情報が保存される。 |
tag | タグの情報が保存される。 |
一つずつ簡単に説明します。
blobオブジェクト
blobはいわゆる「ファイル」の内容を保存するオブジェクトです。
ファイル名の情報は持たず、内容だけが保存されています。
ファイル名はこのあと説明するtreeオブジェクトに保存されます。
treeオブジェクト

treeはファイルが保存されているディレクトリを表すオブジェクトです。
git commit
の操作をすると、commit
に関連する一連のtreeオブジェクトが作られます。
treeオブジェクトに保存されるデータは、blobオブジェクトや他のtreeオブジェクトです。
他のオブジェクトのハッシュ値とファイル名(またはディレクトリ名)を持つ事で、ディレクトリ構造を表します。
commitオブジェクト

commitはコミットの情報が保存されているオブジェクトです。
commitオブジェクトに保存されるのは、前のcommitオブジェクト、トップレベルのtreeオブジェクト、コミット作成者の情報です。
tagオブジェクト

tagはcommitを指し示すオブジェクトで、履歴に関係なくcommitを探しやすくしてくれます。
Gitオブジェクトの説明は以上です。
コメント/ピンバック