【図解】Gitのオブジェクトの説明まとめ

git コマンド

Gitのオブジェクトについて、図を使って分かりやすくまとめます。

この記事は以下のGit公式ドキュメントを参考にしています。

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オブジェクトの説明は以上です。

コメント/ピンバック

タイトルとURLをコピーしました