Gitコマンド入門::Gitオブジェクト(cat-file,tree)第五十一回
みなさんこんにちは! 前回のBLOBに続いて、今回は、Treeを学習していきますね! まあ~ Gitを学習した始めたころから、Working Tree とか、ブランチを切ったりして、その枝別れのイメージを、木に例えてTreeだとか? いたるところで、このTreeって単語が出て来ましたけど、結局のところですね。Treeそのものは、複数のオブジェクトを、まとめる為の入れ物、つまり箱みたいなものです。ただ、その箱の中に、そのまた先の箱の情報も保存できるので、それが繋がりイメージを想像させるので、全体像としては、木という表現なのでしょう。でも、繰り返して言いますが、ただのオブジェクトを複数記述してまとめる為のファイルであり、普段、私たちが利用している、ファイル管理のエクスプローラーであり、OSのファイルフォルダーシステムですね。
こちらは「第十回」で使った。木のアイコン!
前回の記事はこちらから!
git本家本元の情報はこちらから!
今日の課題も前回同様、ここを参考にします!
git update-index --add --cacheinfo
それでは早速、git add コマンドと同じ動作をする、git update-index で、ステージング環境を作成してみましょう!
find .git/objects -type f ハッシュ値を確認
$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/7c/8de0324fd9993d95c716ef054cf6445410f7b4
.git/objects/a3/d9bcc0c12de6bf2d5fd5628cadb13307437e42
.git/objects/50/d97d23f92d7a4c52a992daa8655472551c0a44
// 前回作成したファイルは、4つでしたね。
ハッシュ値のデーターと、ファイル名は、以下のように紐づけします!
- README.md --> 50/d97~
- test_content.txt --> d6/704~
- version_1_0.txt --> 7c/8de~
- version_2_0.txt --> a3/d9bc~
ggit cat-file -p で、再確認!
git cat-file -p 50d97
ということで、ファイル名のハッシュ値は、~ 以下、中略
$ git cat-file -p d6704
test content
$ git cat-file -p 7c8de
version 1.0
$ git cat-file -p a3d9b
version 2.0
git update-index --add --cacheinfo
$ git update-index --add --cacheinfo 100644 \
50d97d23f92d7a4c52a992daa8655472551c0a44 README.md
$ git update-index --add --cacheinfo 100644 \
d670460b4b4aece5915caf5c68d12f560a9fe3e4 test_content.txt
$ git update-index --add --cacheinfo 100644 \
7c8de0324fd9993d95c716ef054cf6445410f7b4 version_1_0.txt
$ git update-index --add --cacheinfo 100644 \
a3d9bcc0c12de6bf2d5fd5628cadb13307437e42 version_2_0.txt
git write-tree で、TREEオブジェクト作成!
$ git write-tree
869487db702cd020150dc37b4370d42ac1d8efa8
$ git cat-file -t 869487db702cd020150dc37b4370d42ac1d8efa8
tree
// tree オブジェクトが出来ました!
早速、git cat-file -p で中身を確認!
git cat-file -p 869487db702cd020150dc37b4370d42ac1d8efa8
100644 blob 50d97d23f92d7a4c52a992daa8655472551c0a44 README.md
100644 blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 test_content.txt
100644 blob 7c8de0324fd9993d95c716ef054cf6445410f7b4 version_1_0.txt
100644 blob a3d9bcc0c12de6bf2d5fd5628cadb13307437e42 version_2_0.txt
$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/7c/8de0324fd9993d95c716ef054cf6445410f7b4
.git/objects/a3/d9bcc0c12de6bf2d5fd5628cadb13307437e42
.git/objects/50/d97d23f92d7a4c52a992daa8655472551c0a44
.git/objects/86/9487db702cd020150dc37b4370d42ac1d8efa8
// そして、tree も同じように、ハッシュ値で保存されていますね!
ここまでの操作で、git add コマンドで、ステージングエリアに、4つのファイルを登録した状態と同じことが再現できましたね!
そして、私の大好きな、16進数のdump!(苦笑)
$ xxd -g 4 .git/objects/86/9487db702cd020150dc37b4370d42ac1d8efa8
0000000: 78012b29 4a4d5530 34336730 34303033 x.+)JMU043g04003
0000010: 31510872 7574f175 d5cb4d61 08b859ab 1Q.rut.u..Ma..Y.
0000020: fc53b7ca 2768e5a4 5b2b5243 8a4265b8 .S..'h..[+RC.Be.
0000030: 5ca08a4a 528b4be2 93f3f34a 52f34af4 \..JR.K....JR.J.
0000040: 4a2a4a18 ae15b871 7b7bbd79 3a31667d J*J....q{{.y:1f}
0000050: 4cc645fd 30aef98f 9f40d596 a5161567 L.E.0....@.....g
0000060: e6e7c51b c61b8095 d6f43e30 f2bf39d3 ..........>0..9.
0000070: 76ea71b1 f7ac3edf 5c4204be 6f41536a v.q...>.\B..oASj
0000080: 0455baf8 e69e0307 759fedd7 8dbf9ad4 .U......u.......
0000090: b376a331 bb739d13 00deec43 c1 .v.1.s.....C.
// とにかく、なんか萌えてくる。仕事している感じになる!(笑)
では、お待たせ! git commit-tree
$ echo '1st' | git commit-tree 869487db702cd020150dc37b4370d42ac1d8efa8
a165f10863e4483609e87baa337a1dc748f47742
$ git cat-file -t a165f10863e4483609e87baa337a1dc748f47742
commit
// blob,tree,に続いて、commit オブジェクトの完成!
// 新しいハッシュ値も出来て無事コミット完了!
$ git cat-file -p a165f10863e4483609e87baa337a1dc748f47742
tree 869487db702cd020150dc37b4370d42ac1d8efa8
author Makoto Shiozumi <shiozumi@esmile-hd.com> 1616037130 +0900
committer Makoto Shiozumi <shiozumi@esmile-hd.com> 1616037130 +0900
1st
// ファイルの中身は、いつもの、git log と同じですね!
// タイムスタンプ=1616037130
// ↓
// 日時(Tokyo)=2021/03/18 12:12:10
//
さあ、いかがでしょうか? tree オブジェクトの中に、blob オブジェクトを4つ入れて、それを、git commit-tree コマンドで実行すると、無事コミットすることが出来ましたね。
そして、出来上がったコミットの中身は、tree のハッシュ値、コミットしたユーザー情報、コメント分、タイムスタンプなどが入っていますね。
タイムスタンプを日付に変換してくれる、ツールサイトあります!(笑)
git log --stat でも確認!
$ git log --stat a165f10863e4483609e87baa337a1dc748f47742
commit a165f10863e4483609e87baa337a1dc748f47742
Author: Makoto Shiozumi <shiozumi@esmile-hd.com>
Date: Thu Mar 18 12:12:10 2021 +0900
1st
README.md | 2 ++
test_content.txt | 1 +
version_1_0.txt | 1 +
version_2_0.txt | 1 +
4 files changed, 5 insertions(+)
--stat オプションを付けると、コミットしたファイル一覧も見れますね!
git reset --hard でファイルのチェックアウト!
とうことで、git reset --hard ハッシュ値 で、実際にファイルをローカルのリポジトリーから取り出します!
$ git reset --hard a165f10863e4483609e87baa337a1dc748f47742
HEAD is now at a165f10 1st
$ ls -a
. .. .git README.md test_content.txt version_1_0.txt version_2_0.txt
// はい、無事、ファイルも取り出せました!
$ git branch -avv
* master a165f10 1st
// ローカルmasterブランチも、git reset で自動に作成してますね。
// では、最後にファイルを確認して!
// 今度は、cat ですね!
$ cat README.md
ということで、ファイル名のハッシュ値は、// 以下、中略~
$ cat test_content.txt
test content
$ cat version_1_0.txt
version 1.0
$ cat version_2_0.txt
version 2.0
$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/7c/8de0324fd9993d95c716ef054cf6445410f7b4
.git/objects/a3/d9bcc0c12de6bf2d5fd5628cadb13307437e42
.git/objects/50/d97d23f92d7a4c52a992daa8655472551c0a44
// 上記の4つは、blob オブジェクト
.git/objects/86/9487db702cd020150dc37b4370d42ac1d8efa8
// tree オブジェクト 上記のblob4つをファイル名付きで保存
// treeの中に、tree オブジェクトの保存も勿論可能!
.git/objects/a1/65f10863e4483609e87baa337a1dc748f47742
// commit オブジェクトは、上記のtreeオブジェクトと、
// 他の情報を保存(コメント、日付、作成者情報など)
今回のまとめ
さあ~ これで、gitデータ構造、Gitオブジェクトについての理解度も深まってきましたね。ほんとうは、これを最初にやるべきでした~~~(苦笑)そして次回は、Treeの中に、Treeを入れ後にしたりなど、もう少し複雑なTreeの状態に挑戦していきますね!
それでは、今回はここまで、お疲れ様でした!
Discussion