Gitオブジェクト是什么东西?

相对于svn,git确实在同一远程存储库下比较时更快。
由于我对git还了解不多,我决定现在去了解一下,然后我发现git是用快照来管理的。因为不需要像svn一样逐步累积差异,所以我认为git很快。

如果考虑到快照的保存,为什么Git仓库不会变得庞大呢?我也产生了这个疑问,但我明白这是通过Git对象的结构来巧妙处理的,所以为了整理自己的思路,我写了这篇文章。

Git对象的类型

    • 4種類のオブジェクトが存在する

 

    SHA-1ハッシュによる識別
種類内容blobオブジェクトファイルに相当treeオブジェクトディレクトリに相当commitオブジェクトコミットのスナップショットtagオブジェクトタグ。今回は対象外

Blob对象

    • ファイルに相当するオブジェクトで、ファイルの中身がzlibで圧縮されている。ファイル名は管理外。

 

    • ファイルの中身にblob <ファイルサイズ>\0をつけたSHA-1ハッシュ値。

 

    • つまり、 ファイルの中身が同じであれば、同じオブジェクトとなる。

git addしたときに生成する

我會試一試

    以下4ファイルの構成で試してみます
│  readme.txt      ファイルの中身:hogehoge
│  sample.txt      ファイルの中身:this is sample
├─subA
│     aaa.txt      ファイルの中身:Hello aaa
└─subB
      bbb.txt      ファイルの中身:hogehoge

git add .で4ファイルをaddした結果、.git/objectsは以下となりました

.git/objects/48/f685c5179595c9edbcfb5ebcc1beafac716857
.git/objects/64/e3d0eb4f3c190bf547221f28a364c49b9df77e
.git/objects/6f/27b4832a80eaa3123c0d1c256c41cd1835b33d
    • ここで4ファイルのハッシュ値を計算してみます。

 

    • blob <ファイルサイズ>\0 <ファイルの中身>をsha-1計算します

blobオブジェクトのハッシュと一致していることが確認できます
ファイルが異なっていても、中身が同じであればblobオブジェクトは共通なことが確認できます

$ (echo -en 'blob 8\0';cat readme.txt) | shasum
48f685c5179595c9edbcfb5ebcc1beafac716857 *-

$ (echo -en 'blob 14\0';cat sample.txt) | shasum
64e3d0eb4f3c190bf547221f28a364c49b9df77e *-

$ (echo -en 'blob 9\0';cat subA/aaa.txt) | shasum
6f27b4832a80eaa3123c0d1c256c41cd1835b33d *-

$ (echo -en 'blob 8\0';cat subB/bbb.txt) | shasum
48f685c5179595c9edbcfb5ebcc1beafac716857 *-
    • 次にこのblobオブジェクトを確認します。git cat-file <オプション> <gitオブジェクト>

 

    -pオプションを使うと、中身が見れました。
$ git cat-file -p 48f68
hogehoge

$ git cat-file -p 64e3d
this is sample

$ git cat-file -p 6f27b
Hello aaa

树对象和提交对象

    • treeオブジェクト

git commitしたときに生成される
ディレクトリに相当
ディレクトリごとに生成される

commitオブジェクト

git commitしたときに生成される
親のcommitを参照している
作成者や日付、コミットメッセージが格納されている

尝试一下

git commit -m “test commit”した結果、.git/objectsは4つ増えていました

.git/objects/06/4bee06635089f2c96c653c71c24e01fe78bbf7
.git/objects/27/7f73e22786e4adfab6ec27ca1aa1baf9187e8d
.git/objects/80/dcb15ab2823857535ee6123204c0aa167ce938
.git/objects/f5/abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a
    このうち3つめはcommitオブジェクトで、残りがtreeオブジェクトのようです
 $ git cat-file -t 064be
tree

$ git cat-file -t 277f7
tree

$ git cat-file -t 80dcb
commit

$ git cat-file -t f5abc
tree
    • treeオブジェクトの中身を見てみます

 

    treeオブジェクトが、ディレクトリごとに生成されていることが分かります
$ git cat-file -p 064be
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    readme.txt
100644 blob 64e3d0eb4f3c190bf547221f28a364c49b9df77e    sample.txt
040000 tree 277f73e22786e4adfab6ec27ca1aa1baf9187e8d    subA
040000 tree f5abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a    subB

$ git cat-file -p 277f7
100644 blob 6f27b4832a80eaa3123c0d1c256c41cd1835b33d    aaa.txt

$ git cat-file -p f5abc
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    bbb.txt
    • commitオブジェクトの中身を見ます

ルートのtreeオブジェクトの存在が確認できます
コミットしたユーザー、タイムスタンプやコミットメッセージが確認できます

$ git cat-file -p 80dcb
tree 064bee06635089f2c96c653c71c24e01fe78bbf7
author hoge <hoge@hoge.com> 1660563865 +0900
committer hoge <hoge@hoge.com> 1660563865 +0900

test commit
commit_80dcb.png

我会再试一次

echo -n “hogehoge” > sample.txtでsample.txtの中身を、readme.txtと合わせました
中身が同じなので、blobオブジェクトは作られないはず。実際にはこんなユースケースないと思いますが

echo -n “abcdefg” > abc.txtで新しいファイルを作ります

git add .しましたが、予想通りGitオブジェクトは1つしか増えていません
変更のないファイルはオブジェクトが作られないため、リポジトリ容量の肥大化を防いでいます

.git/objects/06/4bee06635089f2c96c653c71c24e01fe78bbf7
.git/objects/27/7f73e22786e4adfab6ec27ca1aa1baf9187e8d
.git/objects/48/f685c5179595c9edbcfb5ebcc1beafac716857
.git/objects/64/e3d0eb4f3c190bf547221f28a364c49b9df77e
.git/objects/6f/27b4832a80eaa3123c0d1c256c41cd1835b33d
.git/objects/80/dcb15ab2823857535ee6123204c0aa167ce938
.git/objects/dd/a6eb4b7b86af8aea969498003937b7c8aa46be  これが増えました
.git/objects/f5/abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a
    増えたGitオブジェクトを確認します
$ git cat-file -t dda6e
blob

$ git cat-file -p dda6e
abcdefg

git commit -m “2nd commit”したら、2つ増えました

.git/objects/06/4bee06635089f2c96c653c71c24e01fe78bbf7
.git/objects/27/7f73e22786e4adfab6ec27ca1aa1baf9187e8d
.git/objects/48/f685c5179595c9edbcfb5ebcc1beafac716857
.git/objects/64/e3d0eb4f3c190bf547221f28a364c49b9df77e
.git/objects/6f/27b4832a80eaa3123c0d1c256c41cd1835b33d
.git/objects/72/d0fc47ed60e0f2abdfef26c9d48c2a0b56e3b0  これが増えた
.git/objects/80/dcb15ab2823857535ee6123204c0aa167ce938
.git/objects/a0/4d10c2f7ebd3490d126d88e5979b0c4913b865  これも増えた
.git/objects/dd/a6eb4b7b86af8aea969498003937b7c8aa46be
.git/objects/f5/abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a
    • 増えたGitオブジェクトを確認します

commitしたので、増えた1つは当然commitオブジェクトです
もう1つはルートディレクトリにファイルが増えたので、treeオブジェクトです

$ git cat-file -t 72d0f
commit

$ git cat-file -p 72d0f
tree a04d10c2f7ebd3490d126d88e5979b0c4913b865
parent 80dcb15ab2823857535ee6123204c0aa167ce938
author hoge <hoge@hoge.com> 1660572580 +0900
committer hoge <hoge@hoge.com> 1660572580 +0900

2nd commit

$ git cat-file -t a04d1
tree

$ git cat-file -p a04d1
100644 blob dda6eb4b7b86af8aea969498003937b7c8aa46be    abc.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    readme.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    sample.txt
040000 tree 277f73e22786e4adfab6ec27ca1aa1baf9187e8d    subA
040000 tree f5abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a    subB
commit_72d0f.png
$ git cat-file -p HEAD
tree a04d10c2f7ebd3490d126d88e5979b0c4913b865
parent 80dcb15ab2823857535ee6123204c0aa167ce938
author hoge <hoge@hoge.com> 1660572580 +0900
committer hoge <hoge@hoge.com> 1660572580 +0900

2nd commit

$ git cat-file -p HEAD~
tree 064bee06635089f2c96c653c71c24e01fe78bbf7
author hoge <hoge@hoge.com> 1660563865 +0900
committer korena hoge <hoge@hoge.com> 1660563865 +0900

test commit
$ git cat-file -p HEAD^{tree}
100644 blob dda6eb4b7b86af8aea969498003937b7c8aa46be    abc.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    readme.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    sample.txt
040000 tree 277f73e22786e4adfab6ec27ca1aa1baf9187e8d    subA
040000 tree f5abca5b5cc24cf60e3d72ac4efeb7cb723bcf7a    subB

$ git ls-tree -r HEAD
100644 blob dda6eb4b7b86af8aea969498003937b7c8aa46be    abc.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    readme.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    sample.txt
100644 blob 6f27b4832a80eaa3123c0d1c256c41cd1835b33d    subA/aaa.txt
100644 blob 48f685c5179595c9edbcfb5ebcc1beafac716857    subB/bbb.txt

总结

我想,会不会变成这种感觉呢?如果有错误,请指正一下。

    • Gitはスナップショットで管理しているため、チェンジセット管理のsvnよりも速い

 

    • 変更がないファイルのblobオブジェクトは作られないため、リポジトリ容量の肥大化を防いでいる

 

    blobファイルは、zlibで圧縮されているので、ここでも容量削減に貢献している
广告
将在 10 秒后关闭
bannerAds