2019年3月27日水曜日

git gc --aggressive するそのまえに

Git が遅い!!
そんなときに検索をするとだいたい
「git gc しましょう」だったり、「git gc --aggressive --prune=now」だったりします。

が、試してみても劇的に速くなることってあんまりなくないですか?
特に --aggressive オプションを付けると git gc 自体がくそ長く、その割に効果は感じられなくて残念な結果になることが多いです。
※個人的な感想です

なんか遅い。もう少し深掘りしてみませんか?

GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1
git コマンドは GIT_TRACE を有効にすると、中で何をしているのか追跡できるようになります。
GIT_TRACE=1 git st


git st はエイリアスなので、git status コマンドが呼ばれている様子がわかりますね。
さらに、GIT_TRACE_PERFORMANCE=1 をしておくと、処理時間の計測までしてくれます。

GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1 git st


処理を追えるようになったので、あとはボトルネックになってる部分を見ていけばいいわけです。
(TRACE には他にも項目があります。詳細はこちら→ Git - 環境変数

事例
上に載せたスクリーンショットは、サブモジュールがあるリポジトリでの git status コマンドの計測なのですが、見ていただくとサブモジュールに対してもステータスを確認しにいっているのがわかります。普段なにげなく使っていたコマンドですが、サブモジュールを見に行ってるとは知りませんでした。

サブモジュールの使い方にもよると思いますが、
データ(アセット)をサブモジュールにしているリポジトリでの git status がすごく遅くなっていたため、TRACE するとサブモジュールの status に時間がかかってました。(でかいからな)

自分の場合は、そのサブモジュールで作業することはなく興味のない情報だったので、以下の設定で無視するようにしました。
git config diff.ignoreSubmodule dirty

これで 90% くらい速くなりました。

最後に
速度を求めるなら、ボトルネックを知らなければ効率的な解決はできませんよね!

1 件のコメント: