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したりすると、かなりカオスになりかねません。
取扱には気をつけましょう。

関連記事

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

baba

ゆとりプログラマー。 高校時代から趣味でプログラミングを初め、そのままコードを書き続けて現在に至る。慶應義塾大学環境情報学部(SFC)卒業。BPS設立初期に在学中から参加している最古参メンバーの一人。Ruby on Rails、PHP、Androidアプリ、Windows/Macアプリ、超縦書の開発などを気まぐれにやる。軽度の資格マニアで、情報処理技術者試験(16区分17回 + 情報処理安全確保支援士試験)、技術士(情報工学部門)、Ruby Programmer Gold、AWSソリューションアーキテクト(アソシエイト)、日商簿記2級、漢検準1級などを保有。

babaの書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ