Gitリポジトリの中身を詳細に調べてみた
どのようにファイルが管理されているのか
普段何気なしに使用しているGitがどのようにファイルを管理しているのか気になったのでgit cat-file
コマンドを使用して確認してみました。
git cat-fileコマンド
Gitオブジェクトの内容、サイズ、情報を与えてくれるコマンドです。
今回は、Gitオブジェクトの 内容 を見たいのでgit cat-file -p <object>
を使用していきます。
ファイルのみ
まずはあるファイルがコミットされた時の状態を確認してみましょう。
$ tree
.
└── first.txt
$ git log
commit 46c087d7cd021948bb1dafaf89bcae28dbdb4a75 (HEAD -> main)
Author: xxxxxxxx
Date: Sun Jun 18 23:56:28 2023 +0900
first commit
first.txt
のみがコミットされた状態です。
ここでコミットオブジェクトの中身を見てみましょう。
$ git cat-file -p 46c087d7cd021948bb1dafaf89bcae28dbdb4a75
tree 59b06a677ad85669b18550663b7b666b01e9affa
author xxxxxxxx
committer xxxxxxxx 1687100188 +0900
first commit
tree 59b06a677ad85669b18550663b7b666b01e9affa
という情報が出力されましたが、これはこのコミットがどのようなディレクトリ構造を持っているかを教えてくれるオブジェクト(ツリーオブジェクト)となります。では、またオブジェクトの中身を見てみましょう。
$ git cat-file -p 59b06a677ad85669b18550663b7b666b01e9affa
100644 blob 9c59e24b8393179a5d712de4f990178df5734d99 first.txt
first.txt
というコミットしたファイルの名前が出てきましたね。さらに、blob
という文字列が見えると思いますが、これはブロブオブジェクト、つまり、ディレクトリではなくファイルであることを示してみます。では、同じくオブジェクトの中身を見てみましょう。
$ git cat-file -p 9c59e24b8393179a5d712de4f990178df5734d99
first
オブジェクトファイルの中身を見ると、ファイルの中身を出力してくれます。
今までの結果を図で表してみると以下のようになります。
※ Shape Painterを使用させていただきました。
ディレクトリとファイル
ファイルひとつだけではつまらないので、ディレクトリとその配下にファイルを作成してみましょう。
$ tree
.
├── first.txt
└── second
└── second.txt
$ git log
commit 899109fa34a32597c5ef884719e104f46561cb29 (HEAD -> main)
Author: xxxxxxxx
Date: Mon Jun 19 00:28:53 2023 +0900
second commit
commit 46c087d7cd021948bb1dafaf89bcae28dbdb4a75
Author: xxxxxxxx
Date: Sun Jun 18 23:56:28 2023 +0900
first commit
コミットオブジェクトの中身にツリーオブジェクトが存在するまでは同じためコマンドの結果は省きます。
ツリーオブジェクトの中身を見てみまましょう。
$ git cat-file -p 67551e9fa4d9474ccc1c9a44dbc2b5c1bfaa4aff
100644 blob 9c59e24b8393179a5d712de4f990178df5734d99 first.txt
040000 tree 43dd725f48c270fd09057f8a7d92f446cf05e40e second
first.txt
が存在するのは同じですが、second
というツリーオブジェクトが存在します。これは、このコミットではsecond
フォルダが存在するということを示しています。それぞれのオブジェクトの結果の出力は省略し最終結果のみを図で表してみます。
オブジェクトファイル一覧
色々なオブジェクトを見てきたがそれらは全て.git/objects
に管理されている。
$ tree .git/objects
├── 43
│ └── dd725f48c270fd09057f8a7d92f446cf05e40e
├── 46
│ └── c087d7cd021948bb1dafaf89bcae28dbdb4a75
├── 59
│ └── b06a677ad85669b18550663b7b666b01e9affa
├── 67
│ └── 551e9fa4d9474ccc1c9a44dbc2b5c1bfaa4aff
├── 89
│ └── 9109fa34a32597c5ef884719e104f46561cb29
├── 9c
│ └── 59e24b8393179a5d712de4f990178df5734d99
├── e0
│ └── 19be006cf33489e2d0177a3837a2384eddebc5
├── info
└── pack
例えば9c59e24b8393179a5d712de4f990178df5734d99
というオブジェクトファイルは
├── 9c
└── 59e24b8393179a5d712de4f990178df5734d99
に相当する。
さて、オブジェクトファイルのファイル名、中身はどのように決められているのかについてはGitオブジェクトを参照していただければと思います。
まとめ
通常のディレクトリ構造はディレクトリとファイルで構成されていますが、それぞれがGitリポジトリの文脈では「ツリーオブジェクト」、「ブロブオブジェクト」として管理されていることがわかりました。
Discussion