Python思ってたよりすげー
git-catとは
git-catというのは、gitのオブジェクト(.git/objects/以下にあるアレ)を人様向けにある程度分かりやすく表示してくれるgitのコマンドの一つであるcat-fileを単体のプログラムにしたもの
PHPでGitビューワー組むときに使えるかなと思って最近気になってたPythonで組んでみることにした。
gitオブジェクトの概要
ファイルツリー
gitバージョン管理システムという性質上、少し特殊な構造になっています。詳しいところは別のもっと詳しい方々に譲るとして、git-catを作るのに必要なのは次に挙げるいくつかです。
- .git/refs/heads/ブランチ名
- .git/objects/[0-9a-f]{2}/[0-9a-f]{38}
上のファイルを開くと40桁の16進数が載っていると思います。これはそのブランチの最新コミットハッシュです。(ハッシュを利用しているのは衝突の可能性が極めて低いからですね。)
下は、40桁のハッシュで構成されたファイルが大量に並ぶのは不格好だと考えたのか最初の二桁+残り38桁に分解し、最初の二桁をディレクトリ名としてある程度整理が付くようになっています。(それでも汚いと思うのは自分だけではないはず)
まずは読んでみる
そのまま適当にファイルを開いてもよくわからない文字の羅列しか出てきません。なぜかといえば、それらは全てzlibによって圧縮された文字列だからです。
なのでまずは解凍しましょう。
# !/usr/bin/python
import zlib
import sys
if __name__ = "__main__":
fname = sys.argv[1]
fd = open(fname, "rb");
line = fd.read()
print zlib.decompress(line)
これを適当な場所に保存し、zlibがPythonで使える状態になってるのを確認した上で./git-cat xxx/.git/objects/00/112233445566778899aabbccddeeff00112233とかを試してみると、意味の有る文字列になって表示されたと思います。
やっぱ詳しく知りたい
色々なファイルを試す内に必ず冒頭にtreeやcommitなどの識別子(?)と数字があり、¥0が挟まれた後にそれぞれの内容が入るということが分かると思います。
これの解説か何か無いかなーと思って調べてみるとhttp://linquize.blogspot.hk/2011/10/supplemental-information-for-git.html というページをラッキーなことに発見することが出来ました。
後はひたすら文字列処理をして行くだけなのでコードは割愛しますが、思っていたよりは簡単でした。この調子で作っていけばgitのpython/PHPラッパーも比較的簡単に作ることが出来るのではないでしょうか。