Gerritのコードレビューを複数に分割して実施する

Gerritは1コミット＝1コードレビューを前提とするコードレビューシステムであり、実際に運用していると、コードレビューが乱立することを避けたい思いから、大きな修正内容でも1コミットにまとめてしまいがちになる場合がある

しかし以下を踏まえると、大きな修正内容は分割する方が良いと考えられる

- 1つのコードレビューに過度（数百行程度）の変更が含まれていると、レビュアーの負担が大きい
- 意味ある最小単位でコミットを残せない

本記事では、Gerritのコードレビューを複数に分割して実施する方法と、その具体的手順を紹介する

# 概要
以下2つの方法を紹介する

1. 1つのブランチに複数コミットを行い、同時にプッシュすることで「連鎖」として関連付ける
2. 複数ブランチに個別でコミット・プッシュしたのち、共通の「Topic」を付与することで関連付ける

## 前提とする環境
- Gerrit 3.0.0
- SourceTree 3.2

## 想定する読者
GerritのWebインタフェースとSourceTreeを利用して、以下を実施する手順を知っている

- 1コミット単体のコードレビュー提出
- 1コミット単体のコードレビューでNGとなった場合の修正と再提出

# 1つのブランチに複数コミットを行い、同時にプッシュすることで「連鎖」として関連付ける
この方法は、修正内容を「**依存関係のある複数のコミット**」に分割できる場合に取れる手段である
つまり、修正内容がA・Bの2つに分けられるとした場合、BはAのコミットが適用されていることを前提とする修正であるような場合に適した方法となる

修正内容を「依存関係のない複数のコミット」に分割できる場合は、後述の方法が適している可能性がある

この方法を用いると、Gerritのコードレビュー画面上で、分割した修正内容が「**連鎖**」として表示される
レビュアーはこのリストを**下から順**に辿ることで、コミットを親から子の順で確認できる
![連鎖_Web上での見え方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/421cd797-35c1-eb9c-7630-3f1842fd7273.png)

## SourceTreeでの具体的手順

### 新規にコードレビューを開始する
ローカルリポジトリにてブランチ（`features/modify_func`とする）を作り[^chain_make_branch]、修正内容を複数に分割してコミットする
![連鎖_ローカルでコミット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/d14d84d6-7b3f-907c-7af6-320c238effb6.png)

[^chain_make_branch]: 例として新しく作るブランチ上でコードレビューを行うパターンで紹介しているが、`master`/`develop`など既存のブランチ上でも実施可能である

Gerritのブランチ一覧画面上でリモートブランチを作る
<img width="901" alt="連鎖_Gerritでブランチ作成.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/86455c92-fb63-d810-47a3-8d0446b22187.png">
![連鎖_Gerritでブランチ作成後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/68b3b320-6ea1-45f1-72d4-27288e8f5aff.png)

フェッチしてリモートブランチの情報を取り込み、ローカルブランチに追跡させる
![連鎖_ブランチ追跡.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/c09b44a7-9942-123c-2307-4f19206b5000.png)

以下のように複数コミットが先行していると表示されることを確認する
<img width="922" alt="連鎖_ブランチ追跡後.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/75a63a75-5158-3764-cb62-592bf51fc060.png">

ブランチをコードレビュー用のブランチ（`refs/for/features/modify_func`）にプッシュする [^gerrit_push]
これにより、**先行しているコミット**のコードレビューが開始される
<img width="922" alt="連鎖_PUSH.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/578889c4-6137-ccc4-1340-0507c71b4877.png">

[^gerrit_push]: Mac版のSourceTreeだと、適切なリモートブランチにプッシュされない不具合があるため、その場合は[こちら](https://qiita.com/colomney/items/faa5f169d7b07bf6885d#%E6%96%B0%E3%81%97%E3%81%8F%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%82%92%E9%96%8B%E5%A7%8B%E3%81%99%E3%82%8B)を参照

Gerritのコードレビュー画面上で、同時にプッシュしたコミットが一覧で連鎖として表示されることを確認する
![連鎖_Web上での見え方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/4fbb3e02-1f54-6d98-16bd-45cdd39adb3d.png)

### コードレビューの指摘を受けて修正する
複数ある中の最後のコミットの指摘に対しては、直前のコミットを上書き（amendコミット）にて修正すれば良いが、それ以外の場合は**対話形式でリベース**（インタラクティブなリベース）を利用する必要がある

例えば、以下のように3つのうち2番目のコミットに指摘が入り、修正を行う場合の手順を紹介する
![連鎖_レビューNG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/ee60aebb-6b5b-1d5b-5620-d677a8c83efa.png)

この場合SourceTreeにて、**修正したいコミットの直前**のコミットを選択し、対話形式でリベース（インタラクティブなリベース）を実施する
![連鎖_インタラクティブなリベース.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/541619f4-64e9-2b80-ef11-a9bd64057ed1.png)

出てきた画面にて、修正したいコミットにチェックを入れたうえでOKを押下する
これにより、**チェックを入れたコミットが適用された直後**にリベース作業が一時停止し、手作業でコミットを修正する時間が設けられる
![連鎖_インタラクティブなリベース選択画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/a7a26d09-a426-1d7e-e237-0daed1b2ed14.png)

HEADが修正したいコミットを指していることを確認する
<img width="922" alt="連鎖_インタラクティブなリベースHEAD確認.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/1e93b657-0f31-1ea4-a76b-5c9d479c6a64.png">

この状態でコードを修正し、直前のコミットを上書き（amendコミット）する
![連鎖_インタラクティブなリベースamend選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/ca350e8b-85c2-0b74-61bf-551d2f9399d0.png)

この際、コミットメッセージも適宜修正することができる
ただし、提出済みのコードレビューと紐づけできるよう、最後の行の**Change-Idは編集せず維持**しておく必要がある
<img width="922" alt="連鎖_インタラクティブなリベースamendコミット.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/040ad2a4-b91b-64cb-83f2-47ec9bc1b991.png">

コミットしたのち、リベースを続行する
![連鎖_インタラクティブなリベースを続ける.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/8f2ec609-2423-050f-9b70-92e52d85ef65.png)

以下のように、HEADが最新コミットになればローカルでの修正完了となる
（リベースを続行でコンフリクトが発生する場合は、手動でコンフリクトを解消してリベースを続行を繰り返す）
<img width="922" alt="連鎖_インタラクティブなリベース完了.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/60110a12-bbef-4a88-0d04-49966973eb2b.png">

この状態でプッシュすることで、以下のように新たなパッチセットがGerritにアップロードされて、リモートにおいても修正完了となる
![連鎖_レビュー指摘反映後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/99e452fb-63b3-2b06-5def-7935efacf114.png)

# 複数ブランチに個別でコミット・プッシュしたのち、共通の「Topic」を付与することで関連付ける
この方法は、修正内容を「**依存関係のない複数のコミット**」に分割できる場合に取れる手段である
つまり、修正内容がA・Bの2つに分けられるとした場合、双方のコミットが順番を問わず独立して適用できるような場合に適した方法となる

この方法を用いると、Gerritのコードレビュー画面上で、分割した修正内容が共通の「**Topic**」を持ったもの一覧として表示される
![共通Topic_Web上での見え方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/8ae8bc30-1746-f65d-614b-eace005b9891.png)

## SourceTreeでの具体的手順

### 新規にコードレビューを開始する
ローカルリポジトリにて複数ブランチを作り、各ブランチ上でコミットすることで、修正内容を分割する
![共通Topic_ローカルでコミット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/2c633f75-c00c-f819-1e16-afc220d557a2.png)

Gerritのブランチ一覧画面上でリモートブランチをそれぞれ作る
<img width="992" alt="共通Topic_Gerritでブランチ作成01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/ae09449e-9873-e469-3f6f-29bf5eb58cc9.png">
![共通Topic_Gerritでブランチ作成02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/01188d09-d646-1bb6-af9c-7adaf7246f23.png)

フェッチしてリモートブランチの情報を取り込み、対応するローカルブランチにそれぞれ追跡させる
![共通Topic_ブランチ追跡.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/520fad5d-15e0-8903-bc64-e1c91779ad7e.png)

以下のように各ブランチでコミットが先行していると表示されることを確認する
<img width="922" alt="共通Topic_ブランチ追跡後.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/7c1ba9f5-41ce-3dcb-a89a-124b309f39ae.png">

各ブランチをコードレビュー用のブランチ（`refs/for/features/modify_func_*`）にプッシュする [^gerrit_push]
これにより、**先行しているコミット**のコードレビューが開始される
<img width="922" alt="共通Topic_PUSH.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/dce0873f-fa03-13d1-f9cf-4fc296180756.png">

最後に、Gerritの各コードレビュー画面上で、共通Topicを作成する
![共通Topic_Topic作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/ece65c8e-8916-348d-c666-6e05876285e3.png)
![共通Topic_Topic作成後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/5587fad0-e969-1043-9b96-7c75125dc50e.png)

各コードレビュー画面上で、他の同じTopicを持ったコミットが一覧で表示されることを確認する
![共通Topic_Web上での見え方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/8ae8bc30-1746-f65d-614b-eace005b9891.png)

### コードレビューの指摘を受けて修正する
各コミットは独立したブランチにあるため、1コミット単体のコードレビュー時と同じく直前のコミットを上書きを利用して実施すればよいため、本記事では割愛する