「適切な変更の粒度」について考えることが増えたので、考えていることを流しておきます。
関連する変更がまとまってると嬉しい
1つのPRでついでにやらない、という話は以前もブログに書いた。コードレビューする側に立っても、このPRでやりたいことが何なのか、目的が達成されている (あるいは未来に達成可能である) かが明瞭だとレビューしやすい。
自分は厳密なConventional Commitsはやってないけど、まず土台を用意して、機能を実装して、ちょっと足りないケースを修正する、みたいな感じで、すくなくともcommit単位で追ったら何がやりたいのかは分かるように気をつけているつもり。
小さければ小さいほどよい、とは限らない
1ファイルずつ、1行ずつ変更していったらそれは差分が小さくなるけど、差分が小さければ小さいほどよい、という話ではないと思う。要はバランスです。
これまでフォーマッタが導入されていなかったプロジェクトにフォーマッタを導入する、という場面を考えてみる。ちょっとずつコードをフォーマットしていると別の変更とコンフリクトしまくることが予想されるので、一気に適用してしまう、という戦略も考えられると思う。
コードフォーマッタじゃないけど、テストフレームワークを入れ替えるときはアルファベット順に数十ファイルずつ入れ替えていく、という戦略を取ったことがある。変更が大きすぎるとコードレビューの負荷が高くなるし、変換スクリプトによる変更にバグがあったときに全ファイルやり直していくことになる、という考えでこうしたと思う。
最短ルート (1行書き換えてcommit) が常に最適とは限らない、ということもある。if文を増やしたときのことを考えてみてください。
ところでリファクタリング
id:Sixeight さんのボーイスカウトルールの記事がよかった。自分も圧倒的に先に直す派で、ちょっと難しいタスクをやるために事前に調査してこういうリファクタリングを工程に組み込みます、というのを共有しつつやっている。
最初に作っているうちはまだ仕様が固まっていなかったり、ドメイン知識が足りていなかったのでこう書くしかなかったけど、だんだん全容が見えてきたのでくくり出していく、というのもやっている。
ライブラリのバージョンアップ対応でどうしても大きな非互換変更が必要になるときは、新旧バージョン両方で適用できる実装方法を考えるとか、ライブラリの機能を使っている箇所をラップして互換性を保つとか、そういうことに気をつけられるとよさそう。あとは先まわりしてライブラリのバージョンだけ最新にしておくとか。