オタクのリポジトリって、ダイエットしませんか

お久しぶりっすー
最近ルーティンワークの自動化に力を入れていますね。
途中で、バイナリファイルがたくさん管理してるgitリポジトリの肥大化問題にも直面し、今回はそのダイエットについて、お話したいと思います。

課題(症状)

  • かなり古いプロダクトで、SVNではなく、gitを使ってバイナリファイルを管理した

  • git pull後、該当ディレクトリにて、Enter押すだけでも、プロンプトが帰るまでかなり時間がかかる

  • git checkout [branch]だけで411秒かかる

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sudo GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1 git checkout infra/20200423
    14:53:10.816923 git.c:344 trace: built-in: git checkout infra/20200423
    14:53:11.199887 read-cache.c:1914 performance: 0.287323598 s: read cache .git/index
    14:53:39.084582 preload-index.c:112 performance: 27.884651556 s: preload index
    14:53:39.088442 read-cache.c:1472 performance: 0.003721072 s: refresh index
    14:54:47.321432 read-cache.c:2411 performance: 0.513602372 s: write index, changed mask = 28
    15:00:01.016403 diff-lib.c:527 performance: 313.684637025 s: diff-index
    Switched to branch 'infra/20200423'
    15:00:02.649095 trace.c:420 performance: 411.851091228 s: git command: git checkout infra/20200423
  • リポジトリ全体がなんと50GB+

    • .git/obejcts/pack が46GB+

改善方向

  • とにかく履歴をダイエットしたい
  • いろんな大人の事情で、途中SVNに切り替わることができない
  • 既存ファイルに影響を与えない

トライ

googleセンセイに聞く限り、「git filter-branch」が頻繁に出てきますね。
が、ところどころがパフォーマンス芳しくない報告が散見できます。

もうチョット調べたら、bfg-repo-cleanerというツールにたどり着けました。

よっしゃ~やるぞー
三回分けて実験をしました。

  • –strip-blobs-bigger-than 1M
  • –strip-blobs-bigger-than 200K
  • –strip-blobs-bigger-than 100K

それぞれの検証内容は割愛させていただきます。
結果として、200K => 100Kに減らしたところで、リポジトリ全体が1GBしか容量が削減できなかった。
100Kあたりは限界かと考えられますね。

備考

自分の場合、バイナリファイルが大体100KB~400KBのサイズで、数多く存在するイメージです。

結果

  • サイズ: .git/objects/packのサイズを四分の一以下に

    1
    2
    3
    sudo du -sh .git/objects/*
    4.0K .git/objects/info
    11G .git/objects/pack
  • パフォーマンス:git checkout所要時間は 411s => 14.56s

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sudo GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1 git checkout -b 20200512
    22:20:08.924865 git.c:344 trace: built-in: git checkout -b 20200512
    22:20:09.096295 read-cache.c:1914 performance: 0.125180646 s: read cache .git/index
    22:20:22.258629 preload-index.c:112 performance: 13.162298644 s: preload index
    22:20:22.266180 read-cache.c:1472 performance: 0.003084165 s: refresh index
    22:20:23.136205 read-cache.c:2411 performance: 0.367353451 s: write index, changed mask = 28
    22:20:23.314740 diff-lib.c:527 performance: 0.155411498 s: diff-index
    Switched to a new branch '20200512'
    22:20:23.470696 trace.c:420 performance: 14.564827810 s: git command: git checkout -b 20200512

まとめ

  • Hugeリポジトリ、しんどいっす
  • リソース関連はSVNを使いましょう