Dev Study
← Gitの内部構造から理解する コース

2. ハッシュ値とblobの対応 — Gitはファイル名ではなく中身を保存する

ここが最初の山場です。Gitが保存しているのは「ファイル」ではなく「中身」であり、ファイル名はそこに含まれていません。この事実が、後で出てくるほとんどの挙動の説明になります。

① blobオブジェクトの正確なバイト列

中身 hello\n(6バイト)から blob を作る手順
ファイルの中身"hello\n" = 6バイト
先頭に「型 + 半角空白 + 長さ + ヌル文字」を付ける
"blob 6\0hello\n"これがオブジェクトの全バイト列
この全体をSHA-1にかける
ce013625030ba8dba906f756967f9e9ca394464aこれがblobのオブジェクトID
  • ・ヘッダの \0 はヌル文字(0x00)1バイト。区切りとして使われる
  • ・git hash-object を実行すると、実際にこの値が返る
  • ・長さはバイト数。日本語を含むと文字数とは一致しない

この40文字は覚える必要はありませんが、「中身とヘッダだけから機械的に決まる」という点は押さえてください。誰がいつどのPCで計算しても同じ値になります。

② blobにファイル名は入っていない

同じ中身の2ファイルを add したとき
a.txt中身: hello
backup/copy.txt中身: hello
中身だけからハッシュを計算するので
blob ce013625…オブジェクトDBに1個だけ
  • ・ファイル名が違っても、中身が同じならblobは1個しか作られない
  • ・これがGitが「内容ベース(content-addressable)」と呼ばれる理由
  • ・同じファイルを100個コピーしても、blobは1個で済む

では名前はどこへ行ったのでしょうか。名前は次のレッスンで出てくる tree が持ちます。blobは中身だけを担当します。

③ 1文字変えると別のオブジェクトになる

ファイルを編集したときのDBの変化
hello\n を編集して hello2\n にする
新しい中身のハッシュを計算
blob ce013625…古い中身(残る)
blob 14be0d41…新しい中身(追加)
  • ・古いblobは書き換えられず、そのまま残る
  • ・Gitのオブジェクトは一度作られたら変更されない(追記のみ)
  • ・だから過去のどの時点の中身も取り出せる

Gitは差分ではなく「その時点の中身そのもの」を持ちます。編集は上書きではなく、新しいオブジェクトの追加です。

サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗