🏹

Gitコマンド入門::Gitオブジェクト(cat-file,blob)第五十回

2021/03/18に公開

みなさん、こんにちは! 第五十回となりました! ここまでたくさんの方に購読していただき、いつも感謝しております。また、過去のバックナンバーを見返してみると、誤字脱字もあったりして、ご迷惑をおかけしていましたね。merge を、marge と書いてたり。(^▽^;) これからもどうぞ、よろしくお願いしま~す!

まあ~、Gitコマンドの実務面は、コンテンツ開発をしながら、実際に使用いくなかで覚えていくものもあると思うので、スタディーとしては、第1回~49回ぐらいの内容で、ひとまずOKかなとも思っていますけど、その辺りは、また、後日考えてみたいと思います。

ということで、今日は初心に戻って、本来、私が一番知りたかった、Gitのデーター構造について、学習してみたいと思いますよ~(爆笑)

前回の記事はこちらから!

https://zenn.dev/shiozumi/articles/0b216ef9e58c45

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

初回から、第四十九回までの学習内容のまとめ

  1. Gitの基本操作、追加、編集、削除(add,commit,reset,restore,rm,reflog)
  2. Gitの状態確認、ファイル差分確認(diff,log,status,show)
  3. マージ、コンフィクト、コミットの整理整頓(merge,rebaseコマンド全般)
  4. ブランチ、コミット、タグの理解と操作(checkout,branch,switch)
  5. ローカルブランチ、リモート追跡ブランチ、リモートブランチ(clone,pull,fetch,)
  6. originなどのエイリアス、configファイルの設定項目
  7. コマンド省略なしで、引数を全て指定する。デフォルト値の再確認
  8. Gitのデーター構造、仕組みを理解する。 <ー 今回からココ!

今日の課題は、ここを参考にして進めて行きます!

https://git-scm.com/book/ja/v2/Gitの内側-Gitオブジェクト

このサイト、ほんと、良くできていますよね。正直なところ、私のサイトで学習するよりも、Git Book を先に一読する方が、理解も深まるかと思います。それでも、このサイトを参考にしながら、もうちょっと深堀り、繰り返し学習するようにして、解りやすく進めて行きたいところですね~

それでは、学習スタート・よういどん!【用意どん】

配管(Plumbing)と磁器(Porcelain)

英単語は、私も、もっとも苦手な部分です。ここではあえて説明をしませんけど、Git Bookでは、こんな感じで翻訳されていますね。

  1. ユーザフレンドリーなコマンドは、磁器(porcelain)ここまで扱ってきたコマンド類
  2. 今日から学習していくコマンドは、配管(plumbing)とのことです(苦笑)

では、いつもの、git init から!

$ mkdir func0050 && cd $_
// フォルダー作成と移動を同時に実行、
// 第50回なので、func0050

$ git init
// 毎度のイニシャル!

$ ls -F1 .git
HEAD      <!-- 重要(現在チェックアウトしているブランチ)
branches/
config
description
hooks/
index    <!-- 重要(Staging Area情報)初期段階は未作成
info/
objects/  <!-- 重要(データーベース)
refs/     <!-- 重要(ブランチ情報)
  1. HEAD ファイルは、現在チェックアウトしているブランチを指します。
  2. index ファイルには、Git がステージングエリアの情報を保管(バイナリ)
  3. objects データベースの全てのコンテンツを保管
  4. refs コンテンツ内のコミットオブジェクトを指すポインタ(ブランチ)を保管

シンプルな、キー・バリュー型のデータストアー!

10.2 Gitの内側-Gitオブジェクトには、このように説明されていますね。

そして、その一つ一つのデータのファイル名がハッシュ値化されて、チェーン状に繋がって構成されいて、objectsフォルダー内に保存しています。尚、ハッシュ値38文字のファイル名の中身は、バイナリファイルでした。(^▽^;) 余談ですが、バイナリーファイルだからこそ萌えるのは、昔のアセンブラからの開発者の闘魂ですね! ほんと、今の時代の開発者の方には、どうでもよいことだと思いますけどね(大爆笑)

find .git/objects

まずは、データーが保管される、objects から覗いていきます!

$ find .git/objects
.git/objects
.git/objects/pack
.git/objects/info

$ find .git/objects -type f
$
// まだ、データーファイルは何もない状態です!

git hash-object

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4
// 毎度の長い、40文字のハッシュ値!

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
// フォルダ名:d6
// ファイル名:70460b4b4aece5915caf5c68d12f560a9fe3e4
// いきなりですが、[d6]2文字がフォルダー名となり、
// [70460b~]で始まる、残りの38文字がファイル名となっています!

// そして、このファイルの中身はバイナリーファイルでしたね!
$ xxd -g 4 70460b4b4aece5915caf5c68d12f560a9fe3e4
0000000: 78014bca c94f5230 34662849 2d2e5148  x.K..OR04f(I-.QH
0000010: cecf2b49 cd2be102 004bdf07 09        ..+I.+...K...

まあ~ シンプルな疑問ですが、ファイル名は、どこに入っているのかな?
というか、ファイル名なしで、まずは、データーのみ保存したケースのようですね。
それでは、次は、実際にファイルの中身を取り出していきましょう!

git cat-file -p

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content
// これで、バイナリーファイルの中身が閲覧できますね!

では、さらに復習で、2ファイルを追加!

$ echo 'version 1.0' | git hash-object -w --stdin
7c8de0324fd9993d95c716ef054cf6445410f7b4

$ echo 'version 2.0' | git hash-object -w --stdin
a3d9bcc0c12de6bf2d5fd5628cadb13307437e42

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/7c/8de0324fd9993d95c716ef054cf6445410f7b4
.git/objects/a3/d9bcc0c12de6bf2d5fd5628cadb13307437e42
// これで、3つのファイルが出来ました!

// ファイルの中身は、-p で取り出せます!
$ git cat-file -p 7c8de0324fd9993d95c716ef054cf6445410f7b4
version 1.0

$ git cat-file -p a3d9bcc0c12de6bf2d5fd5628cadb13307437e42
version 2.0

// xxd でバイナリーダンプ!
$ xxd -g 4 .git/objects/7c/8de0324fd9993d95c716ef054cf6445410f7b4
0000000: 78014bca c94f5230 3462284b 2d2acecc  x.K..OR04b(K-*..
0000010: cf5330d4 33e00200 434605e2           .S0.3...CF..

$ xxd -g 4 .git/objects/a3/d9bcc0c12de6bf2d5fd5628cadb13307437e42
0000000: 78014bca c94f5230 3462284b 2d2acecc  x.K..OR04b(K-*..
0000010: cf5330d2 33e00200 434a05e3           .S0.3...CJ..

ということで、ファイル名のハッシュ値は、その時のタイムスタンプあたりを所得しているとおもいますし、先頭は、7804から始まり、文字列、テキストの長さによって、ファイル容量もことなるのでしょう!

では、最後に、README.md を、vi で作成して、ファイルからデータを作成!

git hash-object -w README.md

$ cat README.md
ということで、ファイル名のハッシュ値は、その時のタイムスタンプあたりを所得しているとおもいますし、先頭は、7804から始まり、文字列、テキストの長さによって、ファイル容量もことなるのでしょう!
// 解説文をREADME.md に入れました!(笑)

$ git hash-object -w README.md
50d97d23f92d7a4c52a992daa8655472551c0a44

$ git cat-file -p 50d97d23f92d7a4c52a992daa8655472551c0a44
ということで、ファイル名のハッシュ値は、その時のタイムスタンプあたりを所得しているとおもいますし、先頭は、7804から始まり、文字列、テキストの長さによって、ファイル容量もことなるのでしょう!

// 勿論、ファイルの中身を確認してからの!
// バイナリーダンプで~す!

$ xxd -g 4 .git/objects/50/d97d23f92d7a4c52a992daa8655472551c0a44

0000000: 78015d90 414a0341 10455de7 141e4182  x.].AJ.A.E]...A.
0000010: 60ce9375 2057e85f a5994982 44943164  `..u W._..I.D.1d
0000020: 21469238 6298c9c2 4508c878 984f0fcc  !F.8b...E..x.O..
0000030: ca2b58d5 d909bda8 eeffabdf af1a8ec6  .+X.............
0000040: c3cbfea0 7f417c10 b7c48478 4a75c900  .....A|....xJu..
0000050: 6a4179a3 6ca9fbf8 704fd4d4 05552947  jAy.l...pO...U)G
0000060: ea2e862d 71701b5e 4c6a57e2 06f949fe  ...-qp.^LjW...I.
0000070: 35e5e4b5 7e519784 49af9419 e5b19d86  5...~Q..I.......
0000080: d8d88b9d 7727ca3c e14c328f 05688895  ....w'.<.L2..h..
0000090: ab01f12e efd6d519 7133b8ba 26e69469  ........q3..&..i
00000a0: 2cada1f1 bf02dae7 2c56cb98 bb9b3aa1  ,.......,V....:.
00000b0: 544ed5dc 7274c591 28883dc5 ae1b87fd  TN..rt..(.=.....
00000c0: 9ba73e75 d92251cf 037fa628 35513a5e  ..>u."Q....(5Q:^
00000d0: 32dbc5ef 377abd3f 4ee5bc53           2...7z.?N..S

// さすが、文字数が増えたので、ファイルサイズも大きくなった!

git cat-file -t ハッシュ値!

$ git cat-file -t 50d97d23f92d7a4c52a992daa8655472551c0a44
blob // <-- ファイルの属性です!

blob の他、tree とか、commit などあるようですが、その辺りは、また次回学習していきますね。今回は、こんな感じでまとめておきます!

コマンド スイッチ 補足事項
git cat-file -p バイナリー保存されているファイルの中身を復元!
git cat-file -t オブジェクトの属性を表示 [blob,tree.commit,etc]

BLOB 【Binary Large OBject】とは?

BLOBとは、データベースのフィールド定義などで用いられるデータ型の一つで、テキスト(文字列)や整数のように既存のデータ型としては用意されていない任意のバイナリデータを格納するためのもの。説明がここに書いてありましたので、よろしければどうぞ!
https://e-words.jp/w/BLOB.html

それでは、今回はここまで、お疲れ様でした!

https://zenn.dev/shiozumi/articles/b2bd54b8862a1a
https://twitter.com/esmile2013

Discussion