メインコンテンツへスキップ

中規模プロジェクトにおけるコミット/Pull Request運用ベストプラクティス

📝 はじめに

本記事では、数人規模(2〜6人程度)のPythonプロジェクトを前提に、 GitHubでの コミット粒度・コミットメッセージ・Pull Request(PR)のサイズと運用について、 レビューが破綻せず、履歴が資産として残るベストプラクティスをまとめます。

ここで扱うのは主に以下です。

  • 1コミットの適切な粒度とは何か
  • 1プルリクエストに含める変更量の考え方
  • 複数ファイルを変更する場合のコミット設計
  • コミットログを「将来読む人」のためにどう書くか

ブランチ運用と同様、理想論ではなく現実的に回る運用を重視します。


🧱 基本思想:Git履歴は「記録」ではなく「説明書」

🎯 Git履歴の役割

Gitの履歴は単なる作業ログではなく、

  • なぜこの変更が入ったのか
  • どの単位で意味が完結しているのか
  • どこまで戻せば安全か

後から理解するための説明書です。

数週間後の自分、数か月後の他人が読む前提で設計するのが重要です


🧩 1コミットの適切な粒度

✅ 原則:1コミット = 1つの意味的変更

1コミットは、以下の問いに Yes と答えられる単位が理想です。

  • このコミットは「何をしたか」を一文で説明できるか?
  • このコミット単体で履歴に残っても意味が通じるか?

良い例

  • 「CSVエクスポート機能を追加」
  • 「起動時にNone参照で落ちる不具合を修正」

悪い例

  • 「いろいろ修正」
  • 「WIP」
  • 「とりあえず動くようにした」

1コミット = 1ファイルではありません。「意味の単位」が基準です


📂 複数ファイルを含むコミットは問題ない

以下は同一コミットに含めるべき典型例です。

  • 実装コード + それに対応するテスト
  • モデル変更 + それに伴うバリデーション修正
  • API変更 + 呼び出し側の修正

「この変更がなければテストが壊れる」なら、同一コミットが正解です


✂️ コミットを分けるべきケース

❌ 意味が異なる変更を混ぜない

以下は必ず分けるべきです。

  • フォーマット修正 + ロジック変更
  • リファクタリング + 挙動変更
  • 不具合修正 + 無関係なついで修正

フォーマット変更を混ぜると、レビューも差分追跡も崩壊します


🧹 フォーマット・lint系の扱い

  • 原則:専用コミットに分離
  • 可能なら:専用PR

black / isort / ruff などは、履歴を壊しやすい代表例です


📝 コミットメッセージの書き方

📐 基本フォーマット(推奨)

<動詞(原形)>: <変更内容を簡潔に>

  • add: export results as CSV
  • fix: prevent crash when config is missing
  • refactor: simplify validation logic

「このコミットは何をした?」に即答できるメッセージが理想です


📄 本文(必要な場合のみ)

以下の場合は本文を書く価値があります。

  • なぜこの実装にしたのか
  • 代替案を取らなかった理由
  • 仕様上の注意点

How より Why を書くと、履歴の価値が上がります


🔀 Pull Request の適切なサイズ

✅ 原則:レビュー可能なサイズに抑える

目安として:

  • 差分:数十〜300行程度
  • 変更内容:1テーマ

「5〜10分で全体を理解できるか」が現実的な判断基準です


❌ 大きすぎるPRの問題点

  • レビューが形骸化する
  • 不具合が紛れ込む
  • マージが遅れ、衝突が増える

レビューされないPRは、レビューがないのと同じです


🧩 1 PR = 何コミット?

📌 推奨パターン

  • 作業中:複数コミット OK
  • マージ時:Squash and merge

PR内では履歴の試行錯誤を許容し、main/develop には意味単位だけを残します


🔄 例外

  • コミット単位で意味が明確
  • 後から個別に revert したい

この場合は squash しない判断もあり得ます。

重要なのは「一貫した方針」をチームで共有することです


🧪 テストとPR運用

🧑‍🔬 PRに含めるべきもの

  • 実装
  • 最低限のテスト(または理由の説明)

「テストは後で」は高確率で永遠に来ません


🧯 よくあるアンチパターン

❌ 巨大PRを一気に出す

レビュー不能なPRは、事実上の単独マージと同じです

❌ コミットログが作業メモ

GitはTODOリストではありません

❌ PRタイトルと中身が一致しない

後から検索できなくなります


✅ まとめ:守るべき最小限のルール

  • 1コミット = 1つの意味
  • 意味が違えばコミットを分ける
  • PRはレビューできるサイズに抑える
  • マージ履歴は「将来読む人」のために残す

この運用は、人数増加・CI強化・リリース自動化にもそのまま耐えます