Pure JavaScriptのGitServerを作成しました
1月ごろから細々とやっていたのですが、ようやく作成できました。
デモサイトは以下
https://tiny-git-server.vercel.app/
標準のGitクライアントとisomophic-gitから操作できます。
Gitの内容を理解するのに時間かかったので、そこら辺をつらつら記載していきます。
分からないところもあるので、わかる人いれば教えてくれると助かります。
作成した目的
Webサービス開発時に、Gitリポジトリ作るほどでもない小さい内容をバージョン管理できる仕組みが欲しかった。
しかし、ちょうどよさそうなものがない。(単純なファイルであればS3などでもよいが、複数のファイル合わせてバージョン管理したかった)
結局Gitが良いと思ったがGitHubにリポジトリを作成するほどでもないので、別のGitサーバが欲しく、サーバレスにデプロイできるものが欲しかった。
似ているライブラリなど
https://github.com/bahamas10/node-git-http-server
node上で動くGitServerだが、内部ではGitコマンドを実行している
https://github.com/isomorphic-git/server
isomorphic-gitのサーバの残骸
isomorphic-gitはWeb上でGitクライアントが利用できるもの
構築ノウハウ
Gitサーバで用意するべきエンドポイント
- GET http://localhost:3000/testgitrepo/info/refs
- POST http://localhost:3000/testgitrepo/git-upload-pack
- POST http://localhost:3000/testgitrepo/git-receive-pack
git pushの時には、info/refsで現在のサーバ側のリポジトリ状態を確認し、git-receive-packにて実際に受け取る情報をもらっていく
git pullやcloneの時には、その逆にinfo/refsで現在のサーバ側のリポジトリ状態を確認し、git-upload-packでサーバからクライアント側にアップロードする
Webエンジニアからするとreceiveとuploadがわかりづらいが、もともとsshで受け取る考え方だったからそのコマンドが実施することを記載しているのだろうと思う
Memo
以下の環境変数を変えた状態でgitコマンドを実行することで、どのようなやり取りされているか見える
export GIT_TRACE=1
export GIT_CURL_VERBOSE=1
export GIT_TRACE_PACKET=true
https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0
やり取りされている中身
こちらについては、詳細に記載されているものを見たことはない
頑張ってパケットキャプチャとGitの実装を見つつ解析していった
基本的にやり取りされている内容はバイナリなので、そこを抑えなければならない
(余裕出来たらここら辺もうちょっと書いていきたい。。。)
capablity
Gitではcapablityという追加機能(?)的なものがあり、基本的な動作と特定のcapabilityが指定された際に動く機能がある
本来はすべて実装するべきだが、一部しか実装できていない
各capabilitiesは以下で規定されているが、具体的な内容については記載が見つからない
https://git-scm.com/docs/protocol-capabilities
終わりに
RFCやJSRなどがあれば、それで割と明確に規定が書かれていて、それを実装すればよいのですが、Gitだとそれがなかったです。Gitはプロトコルではなく、ソフトなんだと実感しました。
普段はWeb系として働くことが多いので、細かくバイナリ操作するのは久しぶりでした。ちょっと汚いコードが多いので、リファクタリングしたい。