社内 LT に使ったものを少し改編しています
主に git 初級者の方 (私もですが) に向けた内容だと思います
Qiita スライドモードでご覧頂ければ幸いです
git の内側を知れば git がもっと楽しくなる!
今回は git の使い方ではなく、仕組みの方になります
知っていればトラブルに対処しやすいと思います!
git オブジェクト
git は下記を組み合わせてリポジトリやブランチ等を表現しています
.git/objects に格納されています
-
- blob
-
- tree
-
- commit
-
- tag
git オブジェクト
こんなイメージ
-
- blob (ファイル)
-
- tree (ディレクトリ構造)
-
- commit (コミット情報)
-
- tag (タグ情報)
今回は 1-3 を見ていきます!
では早速 .git/objects を見ていきましょう!
空のリポジトリを作成した時点ではオブジェクトは作成されません
$ mkdir explore-dot-git && cd explore-dot-git && git init
$ find .git/objects -type f
$
git add 前も何も作成されません
$ echo "Alchol 9%" > strong.txt
$ find .git/objects -type f
$
git add すると何やらオブジェクトが作成されます
$ git add strong.txt
$ find .git/objects -type f
.git/objects/29/032df2fd6343ea93bc2c00cd5e93128ba1997f
blob オブジェクト
git cat-file するとオブジェクトを調べられます
cat-file -t (タイプ)
$ git cat-file -t 29032df2fd6343ea93bc2c00cd5e93128ba1997f
blob
cat-file -p (中身)
$ git cat-file -p 29032df2fd6343ea93bc2c00cd5e93128ba1997f
Alchol 9%
blob オブジェクトにファイルの中身が格納されていますね!
という訳で blob オブジェクトはファイルの中身のようです
git commit してみます
$ git commit -m 'add strong.txt'
[master (root-commit) 5fd34a2] add strong.txt
1 file changed, 1 insertion(+)
create mode 100644 strong.txt
オブジェクトが 2 つ増えました
$ find .git/objects -type f
.git/objects/29/032df2fd6343ea93bc2c00cd5e93128ba1997f
.git/objects/48/b394fb164aeb3b5482f3123721df65e208d309
.git/objects/5f/d34a2411bf91577399fd6b9647e37d59e31fa8
増えたオブジェクト 2 つを見てきましょう!
commit オブジェクト (1st commit)
cat-file -t (タイプ)
$ git cat-file -t 5fd34a2411bf91577399fd6b9647e37d59e31fa8
commit
cat-file -p (中身)
$ git cat-file -p 5fd34a2411bf91577399fd6b9647e37d59e31fa8
tree 48b394fb164aeb3b5482f3123721df65e208d309
author sunadorinekop <sunadorinekop@example.com> 1543332950 +0900
committer sunadorinekop <sunadorinekop@example.com> 1543332950 +0900
add strong.txt
commit オブジェクトは commit 情報のようですね!
tree オブジェクト (1st commit)
cat-file -t (タイプ)
$ git cat-file -t 48b394fb164aeb3b5482f3123721df65e208d309
tree
cat-file -p (中身)
$ git cat-file -p 48b394fb164aeb3b5482f3123721df65e208d309
100644 blob 29032df2fd6343ea93bc2c00cd5e93128ba1997f strong.txt
tree オブジェクトはディレクトリ構造の情報のようですね!
このディレクトリは strong.txt がありそのハッシュ値は 29032d... であることがわかりますね!
ここまでのイメージ
こんな感じ?
commit > tree > blob
では、更に commit してみます
更に commit
$ echo "Alchol 3%" > horoyoi.txt
$ git add horoyoi.txt
$ git commit -m 'add horoyoi'
object が増えました
$ find .git/objects -type f
.git/objects/29/032df2fd6343ea93bc2c00cd5e93128ba1997f
.git/objects/47/50679d8ca0d3379dae8abaed6b6013583de548
.git/objects/48/b394fb164aeb3b5482f3123721df65e208d309
.git/objects/5f/d34a2411bf91577399fd6b9647e37d59e31fa8
.git/objects/8b/9e22d4a872621a5ae50655f4ef45bbc6b3e6fc
.git/objects/a5/91a631eaff52e0f32df02d4ba80bc17dd044a1
増えたオブジェクト 3 つを見てきましょう!
blob オブジェクト (2nd commit)
cat-file -t (タイプ)
$ git cat-file -t a591a631eaff52e0f32df02d4ba80bc17dd044a1
blob
cat-file -p (中身)
$ git cat-file -p a591a631eaff52e0f32df02d4ba80bc17dd044a1
Alchol 3%
こちらは 1st commit と同じ感じなので問題無いと思います
commit オブジェクト (2nd commit)
cat-file -t (タイプ)
$ git cat-file -t 8b9e22d4a872621a5ae50655f4ef45bbc6b3e6fc
commit
cat-file -p (中身)
$ git cat-file -p 8b9e22d4a872621a5ae50655f4ef45bbc6b3e6fc
tree 4750679d8ca0d3379dae8abaed6b6013583de548
parent 5fd34a2411bf91577399fd6b9647e37d59e31fa8
author sunadorinekop <sunadorinekop@example.com> 1543333980 +0900
committer sunadorinekop <sunadorinekop@example.com> 1543333980 +0900
add horoyoi
1st commit のオブジェクトと違うのは
parent 5fd34a ...
でしょうか
これは 2nd commit オブジェクトの parent は 5fd34a... であることを示しています
つまり、commit オブジェクトは自分より一つ前の commit オブジェクトのみ知っています
commit オブジェクトのポイント
git は
1st commit <- 2nd commit <- 3rd commit ...
と、git オブジェクトが自分より一つ前の commit を指し示すことによって commit の歴史を表現しています
これが壊れると commit を辿れなって壊れるよ!! (git push -f とか)
tree オブジェクト (2nd commit)
cat-file -t (タイプ)
$ git cat-file -t 4750679d8ca0d3379dae8abaed6b6013583de548
tree
cat-file -p (中身)
$ git cat-file -p 4750679d8ca0d3379dae8abaed6b6013583de548
100644 blob a591a631eaff52e0f32df02d4ba80bc17dd044a1 horoyoi.txt
100644 blob 29032df2fd6343ea93bc2c00cd5e93128ba1997f strong.txt
先ほど commit した horoyoi.txt が増えました
tree オブジェクトはそのディレクトリのファイル等の一覧情報であることがわかります
以上
blob, commit, tree が何となくイメージ頂けましたでしょうか?
## おまけ問題
strong.txt に "double lemon" を追記して 3rd commit した場合どうなるでしょうか?
- 既存の strong.txt の blob オブジェクトに "double lemon" が追加される
- 既存の strong.txt の blob オブジェクトとの差分が新しい blob オブジェクトとして作成される
- 全く新しい blob オブジェクトが作成される
## おまけ問題
strong.txt に "double lemon" を追記して 3rd commit した場合どうなるでしょうか?
既存の strong.txt の blob オブジェクトに "double lemon" が追加される- 既存の strong.txt の blob オブジェクトとの差分が新しい blob オブジェクトとして作成される
全く新しい blob オブジェクトが作成される