#背景
大きな機能の実装が完了し、数ヶ月前に切ったfeatureブランチをdevelopに取り込む時が来ました。しかし、そのままGitHubでPull Requestを出すと...変更が多すぎて表示に非常に時間がかかり、とてもレビューしづらい状態でした。あまりにも差分が大きい場合は一部しかコードが表示されないこともありますよね(※)。そもそもこんな大きな差分はレビューの粒度としても不適切ですし、分割してレビューしてもらうことにしました。
(※上限についてはGitHub公式サイトにまとまっています。)
具体的には今回作業を行ったのはiOSアプリのリポジトリで、変更内容は以下のような感じでした。
- CocoaPodsでのライブラリ追加
- 画像や音声などのリソースファイルの追加
- Embedded Frameworkの作成と追加
- アプリ本体のコードの変更
これらは、例えばCocoaPodsでのライブラリ追加だったらPodsフォルダの下、という風にフォルダで別れていたので、フォルダごとにPull Requestを作成できないか考えました。
#フォルダ毎にPull Requestを出す
前提として機能開発ブランチを featureA
とし、コンフリクトは解消されているとします。
STEP 0: featureAにタグをつける
作業開始地点にタグをつけておきます。(必須ではありませんが、featureAで微調整が続いているような場合に分かりやすくなります。)
git checkout featureA
git tag featureA_alpa
STEP 1: developからbaseブランチを切る
git checkout develop
git branch base
STEP 2: developからcompareブランチを切る
git checkout -b compare
STEP 3: compareブランチにfeatureAをマージ
git merge featureA_alpa
STEP 4: baseブランチにレビュー対象フォルダ以外を取り込む
ここがポイントです!
例えば Sources
以下がレビューしてもらいたい対象の場合は次のようにします。
git checkout base
git checkout compare ":(exclude)Sources"
git commit
checkout時にパス(複数可)を指定すると、ブランチは切り替わらずに指定したファイル・フォルダの内容のみを持って来れます。 :(exclude)
をつけるとそのパスを除外するという意味になります。
STEP 5: compareブランチにbaseブランチをマージ
これによってSources以下の変更だけが差分として表示されるようになります。
git checkout compare
git merge base
git tag review_start
STEP 6: pushしてPull Request !
base
ブランチと compare
ブランチをpushしてGitHub上でPull Requestを作成します。
git push origin base
git push origin compare
これでSources以下の変更のみがPull Requestに表示されるようになりました!
STEP 7: レビュー & 修正
いつも通りGitHub上でコメントのやりとりやコードレビューを進め、指摘の修正を compare
ブランチに行っていきます。
チーム開発をしているとこの間にもdevelopやfeatureAも進んで行ったりしますね!(もっともfeatureAに関してはレビュー対象のフォルダへの変更はちょっと待ってもらいました。)
STEP 8: 修正分をfeatureAに取り込む
修正分のコミットを featureAにリベースします。
git rebase --onto featureA_alpa review_start compare
compare
ブランチを featureA
にマージします。(必要ならPull Requestを出しましょう。)
git checkout featureA
git merge compare
これでSources以下はレビュー済みの状態になりました!
後はレビューが必要なフォルダについてこれを繰り返し、全て完了したら featureA
ブランチを develop
に取り込みましょう!
Pros & Cons
この方法だとレビュー対象のブランチ compare
は featureA
の内容を全て含んでいるため、ビルドしての動作確認が可能です。新機能の仕様をよく知らないレビュワーにとって実際に動かせるのは大きなメリットです。
一方、各Pull Requestの結合部分については議論しにくいので、どう分割するかが大切になります。もし新しく作成したモジュールのインターフェースをレビューしてもらいたいなら、モジュールと利用部分の両方が含まれるようにすると良いかもしれません。