GeekFactory

int128.hatenablog.com

InstaGitという即席Gitサーバを作った

ローカルのGitリポジトリをover HTTPで転送したい時に使える即席Gitサーバを作ってみました.

Gitリポジトリをネットワーク越しに転送するには git daemon を使う方法もありますが,InstaGitはHTTPをサポートしているので,Webブラウザで問題の切り分けがやりやすいとか,他の人に伝えやすいといった利点があると思います.

使い方

最新版のJarをダウンロードして実行します.Java 6以降が必要です.

curl -LO https://github.com/int128/instagit/releases/download/latest/instagit.jar
java -jar instagit.jar

引数にはローカルリポジトリのパスを指定します.引数を指定しないとカレントディレクトリになります.

もし,カレントディレクトリに repo1, repo2 というディレクトリが存在する場合は,

git clone http://localhost:8080/repo1
git clone http://localhost:8080/repo2

でそれぞれを取得できます. .git を含まないディレクトリは無視されます.

また,ブラウザで http://localhost:8080/ を開くと,簡単なWeb UIでリポジトリの一覧を確認できます.

なお,JVMアレルギーがある方にはDockerイメージも用意しております.

docker run --rm -p 8080:8080 -v /repos:/repos int128/instagit

仕組み

GitのJava実装であるJGitと,軽量なAPサーバのJettyを組み合わせています.HTTP GitプロトコルのハンドリングはすべてJGitの GitServlet に委譲しています.Web UIはスタティックなHTMLとJSON APIから成る最小限のものにしています.

なお,JGitはGitBucket, Gerrit, Jenkins Git Pluginなどの多くのプロダクトで使われています. GitServlet の使い方はこれらのソースコードをインスパイアさせていただきました!

久しぶりに Java 6 のコードを書いたら心が折れました.リポジトリのリストを処理したいのにmapやfilterがない,リソースからスタティックファイルを読むだけなのにファイルI/Oがつらい,型推論がないから面倒,とか.本来のやりたいことに集中できる言語や環境の重要さが身に浸みました.

テストコードはSpockでさくっと書きました.

今後の課題

現状でサポートしているのはpullやfetchといった読み込みのみです.pushは今後サポートする予定です.