← Gitの内部構造から理解する コース
2. ハッシュ値とblobの対応 — Gitはファイル名ではなく中身を保存する
ここが最初の山場です。Gitが保存しているのは「ファイル」ではなく「中身」であり、ファイル名はそこに含まれていません。この事実が、後で出てくるほとんどの挙動の説明になります。
① blobオブジェクトの正確なバイト列
ファイルの中身"hello\n" = 6バイト
先頭に「型 + 半角空白 + 長さ + ヌル文字」を付ける
"blob 6\0hello\n"これがオブジェクトの全バイト列
この全体をSHA-1にかける
ce013625030ba8dba906f756967f9e9ca394464aこれがblobのオブジェクトID
- ・ヘッダの \0 はヌル文字(0x00)1バイト。区切りとして使われる
- ・git hash-object を実行すると、実際にこの値が返る
- ・長さはバイト数。日本語を含むと文字数とは一致しない
この40文字は覚える必要はありませんが、「中身とヘッダだけから機械的に決まる」という点は押さえてください。誰がいつどのPCで計算しても同じ値になります。
② blobにファイル名は入っていない
a.txt中身: hello
backup/copy.txt中身: hello
中身だけからハッシュを計算するので
blob ce013625…オブジェクトDBに1個だけ
- ・ファイル名が違っても、中身が同じならblobは1個しか作られない
- ・これがGitが「内容ベース(content-addressable)」と呼ばれる理由
- ・同じファイルを100個コピーしても、blobは1個で済む
では名前はどこへ行ったのでしょうか。名前は次のレッスンで出てくる tree が持ちます。blobは中身だけを担当します。
③ 1文字変えると別のオブジェクトになる
hello\n を編集して hello2\n にする
新しい中身のハッシュを計算
blob ce013625…古い中身(残る)
blob 14be0d41…新しい中身(追加)
- ・古いblobは書き換えられず、そのまま残る
- ・Gitのオブジェクトは一度作られたら変更されない(追記のみ)
- ・だから過去のどの時点の中身も取り出せる
Gitは差分ではなく「その時点の中身そのもの」を持ちます。編集は上書きではなく、新しいオブジェクトの追加です。
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗