Gemfile.lockのマージミスってハマった話
結論を言えば、マージ気をつけましょう、以上って感じなのだけど、少し実験する。
- ruby 2.4.1
- gem 2.6.11
- bundler 1.4.16
例えば以下のような Gemfile
を書いたとする。
source 'https://rubygems.org' do gem 'rake' gem 'rspec' end
これをbundle installすると、以下のような Gemfile.lock
が生成される。
GEM remote: https://rubygems.org/ specs: diff-lcs (1.2.5) rake (12.0.0) rspec (3.5.0) rspec-core (~> 3.5.0) rspec-expectations (~> 3.5.0) rspec-mocks (~> 3.5.0) rspec-core (3.5.4) rspec-support (~> 3.5.0) rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-mocks (3.5.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) PLATFORMS ruby DEPENDENCIES rake! rspec! BUNDLED WITH 1.14.6
DEPENDENCIES
の項に、実際に記述したgem一覧が書かれていて、 GEM
の項には、実際に必要となるgem(依存の依存の・・・と辿ったものを含む)とそのバージョン、そして依存treeが記載されている。
Rubyコンソールで Bundler.require
すると、これらのgemがrequireされ、使えるようになっていることがわかる。
[1] pry(main)> require 'bundler' => true [2] pry(main)> Bundler.require => [Gem::Dependency.new("rake", Gem::Requirement.new([">= 0"]), :runtime), Gem::Dependency.new("rspec", Gem::Requirement.new([">= 0"]), :runtime)] [3] pry(main)> Rake => Rake
ここで、 Gemfile.lock
の GEM
の項のみから rake
を消してみる。
GEM remote: https://rubygems.org/ specs: diff-lcs (1.2.5) rspec (3.5.0) rspec-core (~> 3.5.0) rspec-expectations (~> 3.5.0) rspec-mocks (~> 3.5.0) rspec-core (3.5.4) rspec-support (~> 3.5.0) rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-mocks (3.5.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) PLATFORMS ruby DEPENDENCIES rake! rspec! BUNDLED WITH 1.14.6
人間が見ると、 GEM
の項と DEPENDENCIES
の項が矛盾しているが、この状態で bundle install
しても、 Gemfile.lock
はrakeの行が消えたままで変化しない。
この状態で、もう一度Rubyコンソールを叩いてみる。
[1] pry(main)> require 'bundler' => true [2] pry(main)> Bundler.require => [Gem::Dependency.new("rake", Gem::Requirement.new([">= 0"]), :runtime), Gem::Dependency.new("rspec", Gem::Requirement.new([">= 0"]), :runtime)] [3] pry(main)> Rake NameError: uninitialized constant Rake from (pry):3:in `__pry__'
Bundler.require
は rake
を認識しているが、実際には rake
はrequireされていないので、実行時エラーになる。
まとめ
git mergeするときに Gemfile.lock
のマージをミスると、
- bundlerがエラーを吐いていないことを確認
- 念のため
bundle install
してみる
などをしても気づかず、実行して初めて気づくということが、起こり得るよ。