Gitのキャッチアップメモ

Gitの資料を読んだのでそのメモです。

まずはこれ「たぶんもう怖くないGit」です。

speakerdeck.com

この資料、すごく良かったです。

Git内部の仕組みを理解したら、Gitで普段使っているコマンドが何をやっているのか、腑に落ちた気がしました。

以下は引用多め(自分が覚えておきたところ)の、メモとなります。

メモを見て、興味もった人は資料をみるのがおすすめです。イメージ図も豊富で、とても理解がはかどります。

gitのデータ保存の仕組み

引用です。

  • gitは、オブジェクモデルでデータを保存している
  • gitオブジェクトの集まりで、単なるDAG(有向非巡回グラフ)とポストイットで履歴を管理している
  • コミットは差分ではなく、スナップショット
  • gitの数あるコマンドは、DAGのオブジェクトの追加、ポストイットの移動を行っているだけ

とのこと。コミットは差分を記録していると思っていたけど、スナップショットだったということにびっくり。(スナップショットとは、その時点のバージョンのファイルをまるっと保存している)

キーワード

  • Gitオブジェクト
    • blob, tree, commit, tag
  • リファレンス
    • branch, HEAD, tag

これらの存在を強く意識すると、理解しやすいと。

いつも実行しているコマンドの裏で、これらのオブジェクトが作られたり、リファレンスが変更されたり、しているんですな。

gitオブジェクト

  • zlibライブラリで可逆圧縮されたもの
  • SHA1ハッシュによって識別子がついている
  • オブジェクトは4種類
  • 「.git/objects」ディレクトリを見ると確認できる
  • イミュータブル

ふむふむ。

gitオブジェクトは「git cat-file -p [ハッシュ]」で中身を確認できるらしい。

$ git log -1
commit 4d465c4d2ba118dd97149329c2943ccf6cdd07de (HEAD -> topic-2)
Author: xxx
Date:   Sat Feb 19 11:11:52 2022 +0900
xxx

# commitオブジェクトの確認(commitのハッシュを指定する)
# 親のコミット、このコミットが指す、treeオブジェクトのハッシュを確認できる。
$ git cat-file -p 4d465c4d2ba118dd97149329c2943ccf6cdd07de
tree 76177315e0aa3068850cea28bb0d236dbf042bc9
parent bebce6bdbd485c7c97c9ff104e05d95e34647991
author xxx 1645236712 +0900
committer xxx 1645238192 +0900
xxx

# treeオブジェクトを確認(treeのハッシュを指定する)
# そのコミット時点のファイルツリーを再現できる
# treeオブジェクトやblobオブジェクトが表示される。
$ git cat-file -p 76177315e0aa3068850cea28bb0d236dbf042bc9
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    file2
100644 blob e5d65c44f45d6a90bdb29e09f3bf18e6277de755    hoge

# blobオブジェクトを確認(blobのハッシュを指定する)
# ファイルの中身がまるっと確認できる(ファイル名とかはもってない)
$ git cat-file -p e5d65c44f45d6a90bdb29e09f3bf18e6277de755
ファイルの中身

リファレンス

  • commitオブジェクトのポインタ
  • 簡単に指し示す先を変更できる
  • 「.git/refs」「.git/HEAD」で確認できる
  • 3種類

リファレンスはただのテキストファイルなので「cat」で確認できる

# topic-1ブランチの先頭のコミットのハッシュ値を確認できる
$ cat .git/refs/heads/topic-1
1395f0c5680e2aa097d57e9f0367021758471a60

# HEADはブランチのリファレンス情報が記載されている
# ブランチにコミットするとHEADが自動で追従するのは、そもそもブランチを参照しているから
$ cat .git/HEAD 
ref: refs/heads/topic-2

tag

  • 軽量タグ
    • コミットを参照するリファレンス
  • アノテートタグ
    • tagオブジェクトへのリファレンス
    • tagオブジェクトは、commitオブジェクトへの参照
    • 軽量タグと違い、tagオブジェクトで注釈情報を保持できる

タグは正直使ったこと無いから、ピンと来ていないが、「バージョン1.0.1」で出荷したときのコミット位置は「ここ」みたいに、目印をつけれる機能という理解。

コマンドメモ

gitのログをグラフ形式で表示するコマンド。資料のなかでコミットグラフを確認するときに出てきて、わかりやすかったのでメモ。

$ git log --all --graph

出力するとこんな感じ

$ git log --all --graph
* commit 4d465c4d2ba118dd97149329c2943ccf6cdd07de (HEAD -> topic-2)
| Author: xxx
| Date:   Sat Feb 19 11:11:52 2022 +0900
| 
|     7
| 
* commit bebce6bdbd485c7c97c9ff104e05d95e34647991 (master)
| Author: xxx
| Date:   Sat Feb 19 11:35:55 2022 +0900
| 
|     add file
|   
*   commit 469f1056042ee08a1e2eedf78ce3a6f96fa4bc1e
|\  Merge: 1f4fcad bd0b5ee
| | Author: xxx
| | Date:   Sat Feb 19 11:03:27 2022 +0900
| | 
| |     Merge branch 'topic-1'
| | 
* | commit 1f4fcadae5e290ce124086b1da2be2fbbe0a3ac2

よし、メモをするとさらに理解が捗った気がする。

これで、gitに親しみを持てたかな。