Edited at

「bundle update --sourceで特定のgemをアップデート」は、何がダメで、「--conservative」とは何なのか

のっぴきならない事情により、依存しているgemを除いた特定のgemだけをupdateしたい、という時に

bundle update --source hoge

ってやるとできるよ、とどこかで聞いたことがありました。

久しぶりにのっぴきならない事情があって --sourceオプションを使おうとした時に --conservativeオプションを使わなきゃダメ、と教えてもらいました。

--sourceオプションとなにが違って、なんでこちらが良いのかをググってみても、 「--conservativeを使わなきゃダメなんだ」という記事が引っかかるだけで、何故「--conservativeを使わなきゃダメ」なのかわからなかったので、気になって調べてみました。


conservativeオプション

v1.14以降のbundlerではupdateコマンドにconservativeというオプションがあります。

bundle update --conservative hoge

bundlerのDoc曰く、依存関係にあるgemをupdateしないとのこと。まさにのっぴきならない事情向きな用途です。


Use bundle install conservative update behavior and do not allow shared dependencies to be updated.

https://bundler.io/v2.0/man/bundle-update.1.html



sourceオプション

sourceオプションの方もDocを見てみると、どこのソースのgemを使うのか指定するオプションとのこと。


The name of a :git or :path source used in the Gemfile(5). For instance, with a :git source of http://github.com/rails/rails.git, you would call bundle update --source rails

https://bundler.io/v2.0/man/bundle-update.1.html


ぜんぜんのっぴきならない事情向けじゃないですね。

なぜこのオプションでやりたいことができていたのか、気になって仕方がないのでbundlerのリポジトリを漁ってみました。

すると、過去のissueで、「--sourceが依存関係にあるgemを更新しないで特定の gemだけを更新するノウハウとして広まりつつあるけど、これってたまたまそういう挙動になっちゃってるだけで、--sourceの挙動としてあかんのでは?」というような議論がなされていました。

https://github.com/bundler/bundler/issues/3759

(微妙な英語力でナナメ読みしてるので違ってたらすいません。。。)


結論:「--source」はたまたまそれっぽい挙動だっただけ

--sourceが依存関係のgemまでアップデートしなかったのは「たまたま」だった。

やりたいことを実現するためのオプションは--conservative。