Gitで巨大リポジトリに遭遇した時、軽量に作業する方法

先日巨大なリポジトリに遭遇しクローンするのに1時間ほど要したので調べたことを記事にします。

そしてその後mtgで同じプロジェクトで作業されていた方のHDD壊れた話を聞いて
車と一緒で走れば走るほどHDDは書き込めば書き込むほど壊れやすいんだと思いました笑

Gitリポジトリが巨大な場合、すべての履歴をクローンすると時間もディスク容量も無駄になります。今回、古すぎるデータをクローンせずPCのHDDに負担かけないよう軽量に作業できる方法を模索しました。

まず結果から言うと
今回任意のブランチのみを取得し、最小限のデータで作業する方法を取りました。

シャロークローン

最初は日付でその日以降の変更をクローン出来ないかと調べ

git clone --shallow-since=<date>

を使おうとしたときにエラーが出ていました。原因は調査中です笑(なぜかわかる人は教えてください)

最新一件をクローン

git clone --depth=1 <repositry-url>

master の最新コミットしか取得できない。他のブランチが見えない。

すべてのブランチを shallow clone

git clone --depth=1 --no-single-branch <repositry-url>


すべてのブランチの最新が取得されるが、これでもリポジトリが重すぎる

私の作業の場合他のブランチの履歴は全く必要なかったのでこれも無駄。

特定のブランチのみ取得

git clone --depth=1 --branch <branch-name> <repositry-url>


対象ブランチの最新コミットだけ取得でき、軽量に作業可能!

公式ドキュメント

結論

作業前にリモートでブランチを作成し、そのブランチのみを shallow clone すれば、最小限のデータで作業できる。
Gitリポジトリが巨大な場合は、--depth=1 --branch <branch-name> を活用しよう。


おまけ

以下のこのコマンドを実行することで、不要なファイルやオブジェクトを削除し、データを効率的に圧縮することが可能です。

git gc
オプション説明
–aggressiveより徹底的な圧縮を行い、積極的な最適化を実行
–autogit gcをする必要があるかを確認
–prune=<date>指定した日付よりも古いデータを削除

--prune=nowは到達不能なオブジェクトを直ぐに削除するという指定です。

結果

$ git gc --prune=now
Enumerating objects: 10679, done.
Counting objects: 100% (10679/10679), done.
Delta compression using up to 8 threads
Compressing objects: 100% (10276/10276), done.
Writing objects: 100% (10679/10679), done.
Total 10679 (delta 356), reused 10667 (delta 352), pack-reused 0

git gcコマンドは、主にローカルリポジトリで使用されるコマンドです。このコマンドを実行することで、ローカルリポジトリのメンテナンスを行い、リポジトリのパフォーマンスを向上させると同時に、使用しているPCのディスクスペースを節約になるので定期的にやるとよいかも。

公式ドキュメント