Rokiです。 技術書典11にて頒布されました、KLab Tech Book Vol. 8にて Gitの一部主要コマンドを自作する内容である『ミニマルGitを自作しよう』という章を書きました。 本記事では同章の簡単な内容紹介、また参加にあたっての感想を綴ります。
Gitの基本要素(オブジェクトモデル、インデックス、データ構造等)を図解、 説明し、インデックス化からコミットまでの主要コマンド8つ(add
,cat-file
,diff
,hash-object
,init
,ls-files
,status
,commit
) を実装していく内容が書かれています。
実装ではGitオブジェクトやインデックス等のバイナリを読むためのパーサや pathspecのパーサを読む必要が出てくるのですが、 今回はこれらの実装を簡単に見せるためとしてHaskellでの実装例を示しています。
ただし、単に基本構造の解説や実装コードの解説のみでは独自性がなくつまらない内容となってしまいますので、 たとえば、ワーキングディレクトリ、ワーキングツリー等に関する用語の経緯や100664ファイルモードの話など 筆者が実際に実装する過程で少し疑問に思ったり興味深いと感じた事柄について積極的に脚注やコラムに盛り込みました。 Gitの一通りのコマンドは使っているけれど、 具体的な内部的事情を深くは知らないという方を主対象とした内容になっています。
たとえば、CI等で高速にリポジトリをクローンし git diff
で差分のあるファイル名を取得したいとき blobやtreeオブジェクトを省く、パーシャルクローン1という手法は、クローンの実行時間を抑えることができるため有効です。 blobレスでクローンするとtreeオブジェクトは落ちてくるわけですが、 差分のあるオブジェクト名だけ取得するならtreeオブジェクトにblobオブジェクトのIDが載っていますので、 git diff --name-only
等の実行では、オンデマンドにオブジェクトのダウンロードが発生することはありません。 一方、treeレスでクローンすると、treeオブジェクトのオンデマンドなダウンロードが発生するでしょう。 Gitオブジェクトモデルに関する理解を深めると、 このようなGitオブジェクトモデルの特性を活かした効率化を考えることができるようになり、 実際に、日ごろの業務に役立ることができました。
執筆ドリブン勉強/開発は、ある程度個人の知的好奇心の赴くまま私的に取り組まれることが多いのではないかと考えていますが、 有志が集まって好きな技術について章立てを行い、執筆できるような環境に恵まれたことは幸運でした。 今後も機会があれば、このような活動を幅広く行っていきたいですね。
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。
合わせて読みたい
KLabのゲーム開発・運用で培われた技術や挑戦とそのノウハウを発信します。