作業ブランチではcomposer.lockの変更を最小化してください


お疲れ様です。田中です。

PHPのプロジェクトの作業ブランチ内で、追加のライブラリが必要になったとき composer.json に変更を入れますよね。このときおもむろに composer update を叩くと composer.lock に派手な差分が発生するので、絶対にしないでください

composer update はすべてのパッケージについて、現時点で可能な限り高いマイナーバージョンに上げようとします。当然、自分が master からブランチを切った時点でインストールされていたパッケージのバージョンは、現時点より古くなっています。直接使っているものだけでなく、その依存パッケージも上がります。

いちど composer.lock に大きな差分が発生すると、コミットログが無駄に大きくなるばかりでなく、その後のりベースやマージに支障をきたします。後のリベース/マージ後はつねにフルの composer update が必要となります。本来であれば、コンフリクトするのは本当に必要なバージョン制約か、それ以外はせいぜい content-hash だけで済むはずです。(解消ヒント)

無条件にフルの composer update を強制してしまうことは、未テストなバージョン組み合わせでもいったん受け入れなければならないということです。昨日まで動いていた master への変更影響は極力少なく、でないとせっかく .lock があるのに意味がありません。

というわけで、作業ブランチにライブラリを追加する場合は、composer require vendor/package のみ行ってください。既存パッケージのバージョン制約を変えるなら、composer require "vendor/existing-package:^2.0.1" です。そうすると、これまでにロックされたバージョンはなるべく据え置きで、どうしても変えなければならない内容だけが書き変わります。

また、composer.lock に過剰な影響がないかをコミット前に差分確認してください。もし意図しないバージョンアップがあった場合は、git checkout HEAD -- composer.lock してもとに戻したあと、composer update vendor/package vendor/existing-package というふうに、composer.json 内で 自分が変更したパッケージだけ を更新するようにします。--dry-run オプションで、影響を事前にチェックするのも有効です。

ちなみに、composer.lock の差分がが十分に小さく、GitHub で折りたたまれないということは、レビュアーがどのライブラリのバージョンに影響があったかを目視できるというメリットもあります。

そのうえで、全パッケージの一括更新を行ってもいいのは、リードプログラマーが master (もしくはdevelop) ブランチでのみとします。リードが意図したタイミングで全体のマイナーバージョンを上げ、その結合テストに合格することを確認しなければなりません。

以上、何卒よろしくお願い申し上げます。

追伸: これの npm/yarn 版とか bundler 版とかどなたか...