ファイルの複製を行わずに効率的なバージョン管理を構築する
バージョンの作成やフォークのたびにファイルの完全なコピーを保存すると、容量を浪費してしまいます。10個のファイルがあるプロジェクトで1行だけ変更した場合、10個すべてのファイルを再度保存する必要はありません。
私はLaTeX Writerプロジェクトを構築している際に、この問題に直面しました。高いストレージコストをかけずに、バージョン管理とプロジェクトのフォークを処理する方法が必要でした。
そこで、GitHubの仕組みを調査しました。GitHubは、変更を加えるたびにリポジトリ全体を保存するわけではありません。コンテンツを個別に保存し、参照(リファレンス)を使用してファイルとコミットを紐付けています。
私は主に3つのコンポーネントを使用してシステムを構築しました。
- メタデータ: プロジェクト、所有者、フォルダのIDを保存します。
- ファイルレコード: ファイル名とコンテンツへのリンクを保存します。
- Blobs: 実際のコンテンツが格納される場所です。
このシステムはコンテンツハッシュによって動作します。ファイルを保存すると、システムはコンテンツに基づいて一意のIDを生成します。もしそのコンテンツが既に存在する場合、システムは既存のBlobを再利用します。新しいBlobは作成しません。
このアプローチにより、フォークが簡単かつ低コストになります。プロジェクトをフォークする場合:
- システムが新しいプロジェクトIDを作成します。
- ファイルとフォルダの新しいメタデータを作成します。
- 新しいメタデータを既存のBlobに紐付けます。
フォークの際、実際のファイルコンテンツはコピーされません。小さなメタデータレコードを複製するだけです。
フォークした内容を編集する場合も、プロセスは効率的なままです。
- コンテンツを変更します。
- システムが新しいコンテンツをハッシュ化します。
- その全く同じコンテンツが存在しない場合にのみ、新しいBlobを作成します。
- フォークのメタデータが新しいBlobを指すようになります。
- オリジナルのプロジェクトは、引き続き古いBlobを指したままです。
この手法にはいくつかの利点があります。
- コンテンツの重複排除により、膨大な容量を節約できます。
- フォークが瞬時に完了します。
- バージョン管理が整理された状態に保たれます。
- データベースの肥大化を抑えられます。
重いストレージのオーバーヘッドなしに、GitHubのような機能を実現できます。