bundlerとGemfile.lockの取り扱い
bundlerの役割
bundlerは複数人で同じアプリケーションを動かす時に、gemのバージョン差異で悩まされないように作られました。
このbundlerにより生成されるGemfileとGemfile.lockがあれば他の人と同じ環境を構築できます。
GemfileとGemfile.lock
Gemfileは、必要なgemとそのgemが置いてあるアドレスを書きます。
Gemfile.lockは、最初のbundle installで作成され、そこにはインストールしたgemと、そのgemに必要なgemのバージョンが書かれています。
もし、Gemfileを書き換えてbundle installしたらGemfile.lockも書き換わります。
やってみる
まず、任意のディレクトリで $ bundle init そうしたらそのディレクトリにGemfileが作成されます。 ここでは以下のように書きます。
# A sample Gemfile source "https://rubygems.org" # gem "rails"
これで保存して
$ bundle install
するとGemfile.lockが新規作成され、その中身は
GEM remote: https://rubygems.org/ specs: rack (1.6.4) rack-protection (1.5.3) rack sinatra (1.4.3) rack (~> 1.4) rack-protection (~> 1.4) tilt (~> 1.3, >= 1.3.4) tilt (1.4.1) PLATFORMS ruby DEPENDENCIES sinatra (= 1.4.3) BUNDLED WITH 1.11.2
となっています。
これを見ると、指定通りsinatraは1.4.3が入っていて、これに必要なgemが
rackが1.で、rack-protectionが1.、tiltが1.3.4以上となっています。
実際に確認するとちゃんと従ったgemがインストールされています。
bundle installとbundle updateの使い分け
bundle installをするとGemfile.lockを見て依存関係をチェックしながらインストールされます。
ですが、bundle updateをするとGemfile.lockを無視して最新のgemがインストールされます。
チームで開発する際は滅多なことがない限りbundle updateは実行しないほうが吉だと思います。
Gemfile.lockをコミットするか問題
もう5年前ですがStackOverflowでも話題になってました stackoverflow.com
コミット賛成意見
bundler の作者である Yehuda Katz 氏のブログエントリ yehudakatz.com
コミット反対意見
反対意見の理由の多くは、依存先のgemが環境依存で動かない場合があるからというものでした。
まとめ
自分は、
Gemfile.lockはコミットすべき
と思いました。なぜなら、それぞれの環境で違うバージョンのgemを入れた時、将来それがきっかけでバグが発生した時に対処が困難になるからです。
Gemfile.lockの取り扱いはDevOpsの観点でも非常に重要なので、慎重に取り扱うべきです。
補足
ちなみに、bundlerの作者のYehuda Katz 氏のブログエントリには
gem作ってるならコミットするな
アプリケーション作ってるならコミットしろ
と書いてありました。
参考
非常に参考になりました。ありがとうございます。