← 解説「ブランチの正体 — 40文字が書かれた41バイトのファイル」に戻る
サンプルコードで身につける: ブランチの正体 — 40文字が書かれた41バイトのファイル
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1ブランチファイルを直接見る
ブランチの実体が本当に41バイトのファイルであることを、ls と cat で確かめた実際の出力です。2つのブランチが同じコミットを指しているときは、中身の40文字も完全に同じになります。
$ git branch feature-login
# ブランチはただのファイル。サイズは41バイト(40文字 + 改行)
$ ls -l .git/refs/heads/
-rw-r--r-- 41 feature-login
-rw-r--r-- 41 main
$ cat .git/refs/heads/main
dd2818b6f87da96757d1cd70f43e293660aece49
$ cat .git/refs/heads/feature-login
dd2818b6f87da96757d1cd70f43e293660aece49
# HEADはブランチ名を指している(コミットではない)
$ cat .git/HEAD
ref: refs/heads/main
2ブランチ作成でオブジェクトは1つも増えない
ブランチを作る前後でオブジェクト数を数えた実際の出力です。41バイトのファイルが1つ増えるだけで、オブジェクトDBは全く変わりません。これが「ブランチ作成が一瞬で終わる」ことの正体です。
# ブランチを作る前
$ git rev-list --objects --all | wc -l
8
$ git branch feature-login
# 作った後 — 変わっていない
$ git rev-list --objects --all | wc -l
8
# 切り替えてもオブジェクトは増えない
$ git checkout feature-login
Switched to branch 'feature-login'
$ git rev-list --objects --all | wc -l
8
# 変わったのは HEAD の中身だけ
$ cat .git/HEAD
ref: refs/heads/feature-login
3checkoutで起きていることを分解する
ブランチ切り替えは「HEADの書き換え」と「作業ツリーの並べ直し」の2段階です。オブジェクトは既にDBにあるので、ダウンロードもコピーも起きません。その手順を擬似コードで追います。
Python
4コミットするとブランチが自動で進む理由
HEAD → ブランチ → コミットという二段構造なので、コミット時に書き換わるのは「HEADが指しているブランチファイル」だけです。手動でブランチを動かす必要がないのはこのためです。
Python
540文字を覚えなくてよくするのがブランチ
ブランチもタグも「人間が読める名前 → 40文字」の対応表にすぎません。名前が無くてもハッシュを直接指定すれば同じことができます。ブランチが特別な存在ではないと分かるサンプルです。
# ブランチ名で指定する(いつものやり方)
$ git show main --oneline -s
dd2818b READMEに使い方を追加
# 40文字を直接指定しても全く同じ
$ git show dd2818b6f87da96757d1cd70f43e293660aece49 --oneline -s
dd2818b READMEに使い方を追加
# 名前 → ハッシュ の対応はこれで一覧できる
$ git show-ref
dd2818b6f87da96757d1cd70f43e293660aece49 refs/heads/main
dd2818b6f87da96757d1cd70f43e293660aece49 refs/heads/feature-login
# 名前を解決した結果を確認する
$ git rev-parse main
dd2818b6f87da96757d1cd70f43e293660aece49