これまで GitLFS は遅いだとか大量のファイル管理に向いていないという印象を持っていました。
ですが、まあ大きいバイナリを扱うし遅いのは遅いんですが、やり方によっては現時点でもギリギリ実務に耐えれる程度だと今では思っています。
というわけで、遅さをなんとかする方法をいくつか(少ないですが)書いてみたいと思います。
GitLFSのファイル管理
その前に、GitLFS のファイル管理イメージを持っておくと、そのあとの理解がしやすいのでそこから説明します。
GitLFS は Git の smudge/clean filter の機能を使っています。
git checkout
の際に GitLFS のトラッキング対象としているファイルが含まれていれば、smudge filter を介して GitLFS のストア先から実際のコンテンツを取得し、ポインタファイルをそのコンテンツに置き換えます。
version https://git-lfs.github.com/spec/v1
oid sha256:4665a5ea423c2713d436b5ee50593a9640e0018c1550b5a0002f74190d6caea8
size 36
次に、git add
の際に GitLFS のトラッキング対象としているファイルが含まれていれば、clean filter を介して GitLFS のストア先にある実際のコンテンツを更新し、そのコンテンツから算出したポインタファイルに置き換えます。
これにより、Git 上はポインタファイルだけが管理され、ローカルにはコンテンツそのものがあるという形を実現しています。
なるべく最新のバージョンにする
できるだけ GitLFS のクライアントを最新のバージョンにしましょう。これはとても重要です。
1.0.0 だと push した時に壊れてしまうことがかなりの頻度で発生していたのですが(なぜか Object not found on the server. になったりする)、現時点で最新の 1.4.1 にしたらかなり安定しました。
1.3.0 でレジュームアップロード/ダウンロードができるようになったためかもしれません。
後述の git lfs clone
も 1.2.0 で実装された機能です。
git cloneは使わない
clone する際は git clone
を使わずに、git lfs clone
を使うようにしましょう。
git lfs clone git@github.com:shibukk/lfs-pull-test.git
普通に git clone
した場合、smudge filter が一度に1つのファイルだけしか扱えないため、GitLFS のストアに対し大量のAPIコールが発生してしまいます。
git lfs clone
はこれを解決するために用意されたコマンドで、smudge filter に依存しません。
なので、複数ファイルを並行ダウンロードすることができ、結果高速に clone できます。
smudgeはskipする
git lfs 上にあるコンテンツが何らかの理由で破損している場合、git pull がエラーになってしまいます。
これでは困るので、壊れててもいいからポインタファイルだけを取得するようにしておきます。
git config filter.lfs.smudge "git-lfs smudge --skip %f"
# --globalオプションをつければ全てのリポジトリに対して設定される
このコマンドを実行しておくと smudge が skip されるようになります。
smudge によるコンテンツ置き換えが実行されないので、ローカルはポインタファイルのままですが、git lfs pull
を実行すればコンテンツに置き換えてくれます。
これは同時に高速化も果たします。(clone と同様の理由です)
一点気をつけないといけないのが、こんな感じで手動でコマンドを実行しないといけないので、手順から抜けてしまう可能性があります。
# git pullする場合
git pull
git lfs pull
# git checkoutする場合
git checkout
git lfs pull # git lfs fetch; git lfs checkout; とほぼ等価
なので、githooks の post-merge
と post-checkout
に git lfs pull
を仕込んでおくか、一連のコマンドをまとめたエイリアスを作っておくとよいです。
最後に
これらの Tips は今後変わる可能性があります。
というのも、GitLFS は stream 読み込みなど意欲的な Pull Request が出されているからです。
WIP: long running clean/smudge filter protocol
もっと早くなれば個人的にすごく嬉しいので、引き続き GitLFS の動向は追ってきたいと思います。
2017.02.09 追記
Git LFS checkout times are now up to 80x faster with support for the new filter-process mechanism in Git 2.11 https://t.co/MkfT8VzwRT pic.twitter.com/J61mReGh0i
— GitHub (@github) 2016年11月30日
stream 読み込みの Pull Request が取り込まれて checkout はとても早くなっています。
こんな感じで GitLFS はどんどんよくなっていっています。
ここに記載している Tips はもう必要なくなっていたりしますが、今後も楽しみです!