• 開発

gitリポジトリを軽くしよう!

gitリポジトリの使い方を間違えると、非常に重くなってしまうことがあります。

  • 巨大なファイルをコミットしてしまった
  • 関連プロジェクトを1個のリポジトリにまとめすぎた

まずは犯人を捜す

以下のコマンドで、コミットログをサイズと一緒に見ることができます。

git log --stat

眺めながら、怪しいコミットがいないか探してみましょう。
また、.git/objectsの中から重たいファイルを探して、バイナリエディタで眺めることでも、怪しいファイルの見当を付けられます。

巨大なファイルをコミットしてしまった

gitはソースコード管理システムなので、巨大なファイルを管理するのには向きません。

ちょっとしたwordのドキュメントファイルや画像などは問題ありませんが、100MB以上もあるPSDファイルや動画ファイルなどを入れると、git statusなどの基本的な操作も含めて急激に遅くなってしまいます。

いったんコミットしたものをrmしても、履歴は削除されないので、間違って2GBのダンプファイルをコミット+pushしてしまったような人は以下のようにして削除できます。

git filter-branch --tree-filter 'rm -f path/to/large_file.sql'

ちなみに、32bitマシンで2GBのファイルがコミットされると、gitがOut of memoryを吐いて何も出来なくなりました...

リポジトリをまとめすぎた

SVNでは部分チェックアウトが便利だったので、関連するプロジェクトを1個のリポジトリにまとめることがよくありました。
たとえば、Webシステムのソースコードと、連携するAndroidアプリのソースコードを1個のリポジトリにすると言った具合です。

gitは部分チェックアウトの概念が無く、以下の理由から、ある程度細かい単位でリポジトリを分けた方が運用上楽です。

  • リポジトリサイズが大きくなると、動作が極端に遅くなる
  • 権限をフォルダごとに権限を設定できない
  • railsでcapistranoやjenkinsを使う際にサブディレクトリだと設定が煩雑化する

すでにまとまってしまっている場合は、以下のように分割しましょう。
gitでは分割は出来ないので、実際にはcloneして必要な部分だけ抽出することになります。

git clone origina-repo repo1
cd repo1
git filter-branch --subdirectory-filter dir1

さらに軽量化する

上記の手順をやっても、du -sh .してみると、あまり小さくなっていないことがあります。
この場合、以下のようにすると軽量化できます。

git gc --aggressive
git prune
rm -rf .git/refs/original

まれにgit gcが上手く効いてくれないことがあるので、その場合はcloneし直してから再実行すると小さくなることがあります。

注意点

filter-branchは、履歴を書き換えるコマンドです。

コミットのハッシュ値は当然変わりますし、あとからmergeしなきゃいけないことに気づいたり他の人がpushしたりすると、かなりカオスになりかねません。
取扱には気をつけましょう。

関連記事


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。