gitが大きくなると時間かかってしゃーないと思っていたら、ちょうどatlassianのブログにこんな記事があった。
How to handle big repositories with git - Atlassian Blogs
巨大なリポジトリ を Git で上手く扱う方法
直訳ではなく、読んだことを参考に自分用にメモを記す。これは本当にメモ代わりなので原文を参照した方がいいと思う。
gitが重くなる原因は、「長い歴史」と「デカいファイル」の2つがある。その2つの対処法。
長い歴史に対処する
shallow cloneを使う
gitのhistoryが積み重なると、git cloneに時間がかかる。そのときはshallow cloneを使って、深さを限定してcloneする。
git clone --depth depth remote-url
手元の環境だと23sくらいかかっていたのでも6sくらいに短縮されたから、大きいのだともっと短縮されそう。
filter-branchを使う。
誰かアホなやつが(主に俺が)git add .
とかで不要なバイナリファイルとかを一度入れてしまうと、gitの歴史はずっとそのファイルを持ち続けるので、重くなる。そういう時はfilter-branchを使って、歴史の書き換えをする。
git filter-branch --tree-filter 'rm -rf /path/to/spurious/asset/folder' HEAD
これによって、指定したコマンドをすべてのcommitに対して実行する。俺も何回か使っとことあるけど、gitの歴史の書き換えはすげえ注意が必要。
single-branchを使う
shallow cloneの代わりに、single-branchオプションを使うこともできる。これで、ひとつのbranchのみcloneすれば、重いbranchを無視してcloneできる。
git clone URL --branch branch_name --single-branch [folder]
デカいファイルに対処する
gitってそもそもbinaryファイルを上げることを嫌っていると思っていた(デフォルトではignoreされた気がする)。でも違って、特にバイナリを扱うことに劣っているわけではないらしい(優れてもいない)。
デカいファイルには、状況に応じた対処が必要
- バイナリファイルの変更が大きい時は、差分圧縮は使いものにならない。不必要な差分圧縮を避けるためにも、これらのファイルをdelta offにしておく必要がある。
- 上記の状況だとzlib圧縮は上手く機能しないだろうから、
core.compression 0
もしくはcore.loosecompression 0
に設定をして、圧縮をしないようにしておく必要がある。バイナリファイル以外には悪い影響が出るので、バイナリを別のrepositoryに分けるのをおすすめする。 - git gcによって不必要なオブジェクトを削除したり、ゆるいオブジェクトを一つのパックファイルに整理したりする。これも有効
-
core.bigFileThreshold
をチューニングすることも有効。512MiBより大きいファイルは差分圧縮されるべきではない。(.gitattributes)を設定することを除いて。
sparse checkout
sparse checkoutというものを使えば、明示的に特定のfileやdirectoryのみをgit上で扱えるようになる。
まずは普通にgit cloneする。
git clone
configを設定。
git config core.sparsecheckout true
扱いたいdirectoryを.git/info/sparse-checkout
に記述
echo src/ > .git/info/sparse-checkout
反映させる
git read-tree -m -u HEAD
これを使うと、指定したdirectoryやfileのみを操作できるようになる。(他のファイルは見えなくなる。)
submodule
大きいbinaryなどは別のrepositoryにいれて、そのrepositoryをsubmoduleとする。
Git submodule の基礎 - Qiita
submoduleを使えば、binaryの入っているrepositoryは参照するだけで、一緒に更新したりしないので、重いものを有効に除外できる。
git annexもしくはgit-bigfiles
git-annexを使う。これを使えば、ファイルの中身を取り込まずに管理できる。
git-annex
また、git-bigfilesは、大きいファイルを扱うことを目的としたgitのforkである。
git-bigfiles – Caca Labs