Gitのリポジトリ情報はどのように保存されているか

Gitは実装が直感的ですばらしい。

# ブランチは.git/refs以下
$ ls .git/refs/heads/
master  experimental  maint
# HEADとかは.git直下。
$ ls .git
COMMIT_EDITMSG  ORIG_HEAD    description  index  objects
FETCH_HEAD      RENAMED-REF  gitk.cache   info   refs
HEAD            config       hooks        logs   svn

# インデクスの状態はHEADコミットからの差分としてindexというファイルにバイナリで保存されてる
# 現在のHEADはmasterブランチの先頭と等しい
# 確認した環境がWindows+msysgitだったのでこうなってるけど、
# Linux環境だとHEADはシンボリックリンクで表現されていたような。
$ cat .git/HEAD
refs/heads/master
# masterブランチはコミットオブジェクトc7213...を指している
$ cat .git/refs/heads/master
c7213dafe9f66fe71533186a1083999a0f79bb3e
# オブジェクトの本体はobjects以下
$ ls .git/objects/
00  0e  1d  2c  3c  4f  5f  71  82  93  a1  af  c0  ce  dd  ed  fd
...

$ ls .git/objects/00/
1b7cec0c7d16bd87afebfda2eeb5c19ac5bbe9
2310c0bf3b451e884bf8cd4ed8f87447281880
26a60f7a85b8a78e3cfb62300a579f169c7cb8
2d9b273662a03c20be6c44cf4414ebb42f6a90
98de4f15db70cd9ab559bbc76b4850dc357db1
d327408482452ec1db9c2b819dc4a1cb5444e0

# オブジェクトが多くなったら圧縮してまとめたりもするらしい
# オブジェクトファイルはバイナリで格納されている
$  cat .git/objects/c7/213dafe9f66fe71533186a1083999a0f79bb3e
x搦1Nト0Ei・ワm」eマ8q・B「・cマ8ア6qV・$NO(ク 臊モ・n・妲gZム,・堰・%`GホvF露(イ5ィ
# git showでオブジェクトの情報を表示できる
$ git show c7213daf
commit c7213dafe9f66fe71533186a1083999a0f79bb3e
Merge: c72c08e 4175f13
Author: todesking <discommunicative@gmail.com>
Date:   Fri Oct 23 14:02:18 2009 +0900
...
# 他にcat-fileとかls-treeとかのコマンドもつかえる
# reflogはlogs/ブランチ名
$ cat .git/logs/HEAD
756ac987b0e295b9e95511b7f768c535f9b6dffd 0cf974ef634d8465d350f892cbdd58c0d3d7527f todesking <discommunicative@gmail.com> 1255784778 +0900       commit: remove unused old files.
002310c0bf3b451e884bf8cd4ed8f87447281880 0cf974ef634d8465d350f892cbdd58c0d3d7527f todesking <discommunicative@gmail.com> 1255786294 +0900       HEAD^: updatingHEAD
0cf974ef634d8465d350f892cbdd58c0d3d7527f 002310c0bf3b451e884bf8cd4ed8f87447281880 todesking <discommunicative@gmail.com> 1255786345 +0900       002310c: updating HEAD
...