【Python】1つのPRに混ぜるな危険!「関心の分離」でレビューしやすいプルリクエストを作る方法

ある機能追加のプルリクエスト(PR)を開いたら、ロジックの変更だけでなく、全く関係のないファイルのリファクタリングや、コードフォーマッターによる大量のスタイル修正まで含まれていて、レビューにうんざりした経験はありませんか?

このような、複数の目的が混在した「巨大なPR」は、レビューの質を低下させ、バグを見逃す原因となり、チームの開発速度を著しく妨げます。

優れたPRの原則は、ソフトウェア設計の**「単一責任の原則(Single Responsibility Principle)」と同じです。すなわち、「1つのPRは、1つの関心事にのみ責任を持つべき」**ということです。今回は、なぜPRを小さく、目的に集中させることが重要なのかを解説します。

目次

アンチパターン:「ついで修正」が詰め込まれたPR

例えば、あなたのタスクが**「商品の割引価格を計算する関数を追加する」**ことだったとします。作業中に、あなたは別のファイルにある古いコードや、プロジェクト全体のコーディングスタイルの乱れに気づきました。そして、「ついでに」それらも修正して、一つのPRにまとめてしまいました。

悪いPRの例:3つの異なる関心事が混在

PRタイトル: 新機能追加と全体的なクリーンアップ

--- a/products/services.py (本来の目的:機能追加) ---
+ def apply_discount(price, discount_rate):
+     """割引後の価格を計算する"""
+     return price * (1 - discount_rate)

— a/users/models.py (無関係なリファクタリング) —

  • def get_full_name(self):
  • return self.first_name + ' ' + self.last_name
  • @property
  • def full_name(self):
  • return f'{self.first_name} {self.last_name}'

— a/settings.py (無関係なフォーマット修正) —

  • INSTALLED_APPS=[
  • 'app1',
  • ]
  • INSTALLED_APPS = [
  • "app1",
  • ]

このようなPRは、レビュアーにとって悪夢です。

  • 認知負荷の増大: レビュアーは、①新機能のロジック、②ユーザーモデルのリファクタリング、③設定ファイルのスタイル修正という、全く異なる3つの文脈を頭の中で切り替えながらレビューしなければなりません。
  • 重要な変更が埋もれる: 最もレビューしてほしいはずのapply_discount関数のロジックが、大量の「ノイズ」に埋もれてしまい、バグが見逃されるリスクが高まります。
  • 承認・却下の判断が困難: もし、割引ロジックは完璧でも、Userモデルのリファクタリングにバグがあった場合、このPR全体を差し戻すしかありません。問題のない変更まで、ブロックされてしまいます。

解決策:関心事ごとにPRを分割する

上記の「悪いPR」は、以下のように3つの独立したPRに分割するべきでした。

PR①:フォーマット修正 (粒度:極小)

タイトル: STYLE: settings.py にコードフォーマッタを適用 内容: 機械的な修正であり、レビュー負荷はほぼゼロ。すぐにマージできます。

PR②:リファクタリング (粒度:小)

タイトル: REFACTOR: Userモデルのget_full_nameをプロパティに修正 内容: 既存の振る舞いを変更しない、安全なリファクタリングであることをレビュアーはすぐに確認できます。

PR③:機能追加 (粒度:小)

タイトル: FEAT: 商品の割引価格を計算するサービス関数を追加 内容: レビュアーはこのPRの核心である、新しいビジネスロジックのレビューに100%集中できます。

このようにPRを分割することで、一つ一つのレビューは数分で完了し、それぞれが安全かつ迅速にマージされていきます。


集中したPRを作成するための実践的ガイドライン

  1. PRの目的は一つに絞る: 機能追加、バグ修正、リファクタリング、スタイル修正、ドキュメント更新など、PRの目的を明確に一つに定めましょう。
  2. リファクタリングと機能追加を分離する: 新機能を追加するために既存コードのリファクタリングが必要になった場合、まずリファクタリングだけのPRを作成し、先にマージさせましょう。クリーンな土台ができた後で、本命の機能追加PRを作成すれば、差分は本当に新しいコードだけになり、レビューが非常に容易になります。
  3. コミット前に差分を確認する: git commitを実行する前に、git diff --stagedやIDEの差分表示機能を使い、意図しない変更(デバッグ用のprint文、自動フォーマットによる不要な差分など)が含まれていないかを確認する習慣をつけましょう。
  4. PRの粒度を小さく保つ: もし一つの機能が大きすぎるなら、前の記事で解説したように、それを複数の小さなステップに分割し、それぞれを別のPRとしてマージしていくことを検討しましょう。

まとめ

プルリクエストは、レビューというコミュニケーションのための単位です。そして、効果的なコミュニケーションの鍵は、一度に一つのテーマに集中することです。

PRに「ついで修正」を混ぜないことは、単なる作法ではありません。それは、レビュアーへの敬意の現れであり、チーム全体の開発サイクルを高速化し、コードの品質を向上させるための、極めて合理的な戦略なのです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次