1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

git の仕組み - git オブジェクト (git LT vol.2)

Last updated at Posted at 2018-11-28
1 / 26

社内 LT に使ったものを少し改編しています
主に git 初級者の方 (私もですが) に向けた内容だと思います
Qiita スライドモードでご覧頂ければ幸いです


git の内側を知れば git がもっと楽しくなる!


今回は git の使い方ではなく、仕組みの方になります
知っていればトラブルに対処しやすいと思います! :smile:


git オブジェクト

git は下記を組み合わせてリポジトリやブランチ等を表現しています
.git/objects に格納されています

    1. blob
    1. tree
    1. commit
    1. tag

git オブジェクト

こんなイメージ

    1. blob (ファイル)
    1. tree (ディレクトリ構造)
    1. commit (コミット情報)
    1. 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 が何となくイメージ頂けましたでしょうか? :thinking:


## おまけ問題

strong.txt に "double lemon" を追記して 3rd commit した場合どうなるでしょうか?

  1. 既存の strong.txt の blob オブジェクトに "double lemon" が追加される
  2. 既存の strong.txt の blob オブジェクトとの差分が新しい blob オブジェクトとして作成される
  3. 全く新しい blob オブジェクトが作成される

## おまけ問題

strong.txt に "double lemon" を追記して 3rd commit した場合どうなるでしょうか?

  1. 既存の strong.txt の blob オブジェクトに "double lemon" が追加される
  2. 既存の strong.txt の blob オブジェクトとの差分が新しい blob オブジェクトとして作成される
  3. 全く新しい blob オブジェクトが作成される
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?