Gitもオブジェクトだった…!

Gitを一言で言うなら
スナップショットをバージョン毎に管理できるもの。
とざっくりとしか認識していなかった。 そして、構造がいまいちわかりづらくて難解。。
が、チーム開発になると否が応でもコンフリクトにぶち当たるので、理解を深めざる得ない…!
大変そして面倒😱そんな感覚でしかいなかったが、Gitの内部構造を知り、少しだけ面白さを感じた。

Gitの内部

Gitは洗練されたオブジェクトモデルを、雑多なコマンド群が包み込む構造になっている。

オブジェクトモデル  
プログラムと関連するデータをまとめたオブジェクトを、ひとつのモデルとして把握する考え方。オブジェクト指向プログラミングでは、個々のモデルを組み合わせてプログラミングを行うため、ソースコードの作成後も全体を整理して把握できる。  
Gitでいうとオブジェクトを単位としたデータ構造のこと。  

Gitのリポジトリ作業ディレクト.git ディレクトで構成されている。
直接操作できるのは作業ディレクト
作業ディレクトリの一番上の階層に.gitディレクトが位置しておりリポジトリの本体になる。

.gitの中身

  • Gitオブジェクト
  • リファレンス
  • インデックス

主に上記で構成されている。

Gitオブジェクトの構成

  • .git/objectsディレクトリに格納されている。
  • Git オブジェクトの集合をGitオブジェクトデータベースと呼ぶ。
  • 1 個のGit オブジェクトは 1 個のファイルに書いてある。
  • オブジェクトの数が増えてくると、複数のオブジェクトが pack 形式と呼ばれるファイルにまとめられる。

Gitオブジェクトは4種類ある

  • tree → ディレクト
  • blob → ファイル
  • commit → コミット
  • tag → タグ

Git オブジェクトは、ID (オブジェクト名)で区別されている。
ID は40 文字の 16 進数 (0〜9 と a〜f)になっている。
ID の先頭2文字分ディレクトリがあって、のこり38 文字がファイル名となる。

.git/objects/2文字/38文字

ID だけ見てもオブジェクトの種類 (tree、blob、commit、tag) は区別がつかない。
4種類のオブジェクトがごちゃ混ぜに.git/objects ディレクトリに格納されている。

Gitオブジェクトを見てみる

試しに、bootcampのGit オブジェクトをlsコマンドで確認。

bootcamp % ls .git/objects     
00      11      22      33      44      55      66      78      89      9a      ae      bf      d1      e3      f5
01      12      23      34      45      56      67      79      8a      9b      af      c0      d2      e5      f6
02      13      24      35      46      57      68      7a      8b      9c      b0      c1      d4      e6      f7
03      14      25      36      47      58      69      7b      8c      9d      b1      c2      d5      e7      f8
04      15      26      37      48      59      6a      7c      8d      9e      b2      c3      d6      e8      f9
05      16      27      38      49      5a      6c      7d      8e      9f      b3      c4      d7      e9      fa
06      17      28      39      4a      5b      6d      7e      8f      a0      b4      c5      d8      ea      fb
07      18      29      3a      4b      5c      6e      7f      90      a3      b5      c6      d9      eb      fc
08      19      2a      3b      4c      5d      6f      80      91      a4      b6      c7      da      ec      fd
09      1a      2b      3c      4d      5e      70      81      92      a5      b7      c8      db      ed      fe
0a      1b      2c      3d      4e      5f      71      82      93      a6      b8      c9      dc      ee      ff
0b      1c      2d      3e      4f      60      72      83      94      a7      b9      ca      dd      ef      info
0c      1d      2e      3f      50      61      73      84      95      a8      ba      cb      de      f0      pack
0d      1e      2f      40      51      62      74      85      96      a9      bb      cc      df      f1
0e      1f      30      41      52      63      75      86      97      aa      bc      cd      e0      f2
0f      20      31      42      53      64      76      87      98      ab      bd      ce      e1      f3
10      21      32      43      54      65      77      88      99      ac      be      cf      e2      f4

たくさんある〜!IDの最初の2文字ってことか。00を見てみる。

bootcamp % ls .git/objects/00
104a70195ba867f524aee7f8b224ae9e9ee362  
3ce4707a48f048eee30f3bee2121c974629d7e
242b0e61d9767f99bc64dbacdb8164e9e12809  
9e52d50a8b6fd6f14529e64445ee45cfabab70

まとめられているpackも見てみる。

bootcamp % ls .git/objects/pack                                                                
pack-0c613c3e2fb0c90b7a5f7cbbe754016f70a4b8d5.idx       
pack-789e4c7b0e70a09e94edf046238faf579c2405ab.idx
pack-0c613c3e2fb0c90b7a5f7cbbe754016f70a4b8d5.pack      
pack-789e4c7b0e70a09e94edf046238faf579c2405ab.pack
pack-0ed1f058b24a2b64c158ef1fb3494dd476bdeff7.idx       
pack-7a904cea9764cf4c9d5ce0386c6e4966f3dc14a5.idx
pack-0ed1f058b24a2b64c158ef1fb3494dd476bdeff7.pack      
pack-7a904cea9764cf4c9d5ce0386c6e4966f3dc14a5.pack
pack-1bc504594b6625758798d584835e59059fa4a7e3.idx       
pack-7e1f9731e9f8fa5c93d63952a67b74d25ac80928.idx
pack-1bc504594b6625758798d584835e59059fa4a7e3.pack      
pack-7e1f9731e9f8fa5c93d63952a67b74d25ac80928.pack

以下永遠につづく

たくさんまとまってる〜!

拡張子のpackidxを調べるとgit gcと打つと手動で圧縮する方法があるようだ。

まずはGitのオブジェクトを確認して  
`find .git/objects/ -type f`  

ファイル容量も確認して    
`du .git/objects/`  

オブジェクトをpack
`git gc`

すると、ファイルがまとめられて容量を減らすことができる。  
よくできている…!

idx,、packの中身を確認したい場合は以下で確認できる。

git verify-pack -v .git/objects/pack/**ID**

試しに一つのidxの中身を見てみる。

bootcamp % git verify-pack -v .git/objects/pack/pack-0c613c3e2fb0c90b7a5f7cbbe754016f70a4b8d5.idx
c4603ba969b392ba7a6a6dac72e7ab1f4c684dc3 commit 280 226 12
09e6e7f86cb94ce2ac88ef1422757978b1d0121b commit 243 197 238
9e01dc433b28108371798bfa6cba2afa6688356d commit 318 262 435
dcd74a9552f8cda899a6c3f150112a17a3d34711 commit 278 232 697
44efdaadde5f2b9c3cb3748fb392f0f989f6c164 commit 312 247 929
b33d1cd5267e581ff1c4cb616b16ae295b88ca8f commit 303 244 1176
780e1c51e7ad14f551d32025c2dc403492a5a0a9 commit 309 252 1420
3cd6019f8df001e2c8b43ae52b7963b1c859a1b0 commit 257 206 1672
48a4629a60149651b79fc71d1de837d31c28af67 commit 318 250 1878
0983b094c0547ba858bffffac043057f05d37625 commit 350 292 2128
84b94cc51f600e2291f79d72077c623ee660afba commit 284 235 2420
0d816d71291a6e352b90150365ef3848d42df0ab commit 273 224 2655
afd2ac185987ee8a3cc801c350accb9ba170b9be commit 274 246 2879
6f2f7f1099a8e413fd252c2c7051acc3b5e3c909 commit 314 270 3125
fd3b0190596e8a8eb45049c61fb4d8b1b48a1386 commit 321 271 3395
fd2708a15f4f0437897bc30869fd0e1565ca79bd commit 294 233 3666
f85e9fdb4c96e074aae01766b2c915597c1ce050 commit 291 224 3899
774a37ea47fdb8b2317d9a650f1d81296bf908b9 commit 288 233 4123
ceb790b23430275fba4b0399c6a2c65034fdeb5d commit 273 226 4356
bb22d9d690e7707206001fba48b4cac04235a9f8 commit 248 221 4582
6dc4b2df2543a18a3ab1da844f617cc35da565b2 commit 236 205 4803
d834f02f53a3a40514314b4081965931fc738072 commit 301 263 5008
8a1a744d8fd418b8889e6b7195dc712bf01a0714 commit 255 225 5271
1f45da55c184b7116ed8c8cad574e68a1bd8ef14 commit 271 242 5496
e0dfad2f266e3ab13a245b25794afea7d089cd4d commit 296 240 5738
9ec51e90b77e126a0d845571fc54a67c3e4c9546 commit 372 303 5978
67c96a46f69eef4b6659f431d0ca4b0c726959e5 commit 217 172 6281
af71f50d7c719935dd99fb36ce6a5473ca2c6e9f tree   33 64 6453 1 ebc30cd0e2bc22c72d42e91e7374c5a836cec0a0
fb0349903e3d30108e2b2c39a82dd91d92532ac5 tree   28 61 6517 1 996b77faf34b5643c31426ee14fa49a2a0313833
36a255c4a3d418fd5dcbd34e15e8df332bd7acba tree   33 64 6578 1 7f503601a9a7e8e82ab25499228f762a6857b3d9
9fe2c91017c131cd3f4afe318b85184d8172d095 tree   30 63 6642 1 21f207ac39d2cba0c49c2f6fd043906a3ae7b38e
c3d6eba6cf2593bcdb154d847737eef59dabead2 blob   23 53 6705 1 5d39bd10a377c480643546514f2be8ce243083fc
8b492ea3533f18738ef106e0df2c0bdb81fa3b06 tree   33 64 6758 1 6778d6eb5aa42a4c06af532fe013e1d6b39515ea
e5accb59f2cb37daa6580d18313b69017b63638a tree   30 63 6822 1 9993a1087312f7ef3a2e1b4a67abf20b8f0f9b22
ac4989bbbf5063dab67f59da9c025b94a8310fb3 tree   33 64 6885 1 602346e945773889900153c4b2a10cafaf1daaa4
0595c85bde812255718d508a7d3f64f367312cfd blob   16 47 6949 1 f93438b27abffa135b04edfed6814b07eefd957d
dd49a973e68fb47beeb8de82c311388621e0e426 tree   112 145 6996 1 6778d6eb5aa42a4c06af532fe013e1d6b39515ea
fbe929118560ce53f10970b1a3a3c3bf01a1111b tree   125 154 7141 1 9993a1087312f7ef3a2e1b4a67abf20b8f0f9b22
731774490dad4c22b11bc1eabe9e882f24da7555 tree   27 58 7295 1 e98486c2d799354fedcf078626a4272ba4bf94bc
86ba499e0e64f12b5d940b0120c466a4b8b2092d tree   85 118 7353 1 8ae59f919da34341bd1d096e1f6e8e85700ab713
9e44807393cccfd009105d84945f9f468680aa41 tree   33 64 7471 1 8e6df3565dd9eef9158575da69f50c4bacf6c56e
40bca6b4d380cc88bd3f07579160b24cbd24699b blob   88 102 7535 1 117561673e4f048677c30ef38c3d20111b9e44b8
9530fc0635c9983fcf5bdf5742065af3a76f3571 tree   67 97 7637 1 4bcdaa99e55c575719ab06dc9e542ba01bab24b0

以下永遠につづく

この先、Gitを圧縮する機会なんて来るのだろうか?と思いつつもGitを深堀することができて楽しかった😃

参考にさせて頂きました🙏
Git の仕組み (1) - こせきの技術日記
Gitコマンド入門::Gitオブジェクト(Packfile)第五十九回

そんな、私が参加しているコミュニティは…

bootcamp.fjord.jp

以後、お見知り置きを。

最後までお読み頂きありがとうございました。