こんにちは。
開発本部 フィーチャー部 会計・決済グループでエンジニアをやっている ぺい です。
みなさん、PullRequest 作っていますか?
本記事では、私が普段 PullRequest を作る中で、レビュアーにとってレビューしやすく読みやすくするために意識しているコミットの積み方の工夫についてお話しします。
※ 私の主観が多く入っている点について、予めご了承ください。
前提
以下を、本記事の前提条件とします。
- GitHub を利用している
- PullRequest は最終的に
Squash and Merge
でマージ先のブランチに取り込まれる
実装者の開発ストーリーを追体験できるようなコミットを積み重ねる
例として、Ruby on Rails を使って新しく API を追加するケースを考えてみます。User モデルがあるとして User を新規作成する API を実装する、としましょう。
極端な例ですが、この変更内容に対して以下のように 1commit にすべての変更が詰め込まれていたとします。
- User を新規作成する API を追加 (+300)
この場合、レビュアーは Files changed
から300行の変更を自ら紐解いていかなければなりません。これは、あまりレビュアーに優しい状態とは言えないでしょう。
一方、以下のようにコミットが分かれていたらどうでしょうか (上から下に流れるものとします)。
- users テーブルを追加するマイグレーションの追加 (+20) - bin/rails db:migrate を実行 (+30) - ルーティングの定義を追加 (+1) - User の作成処理を実装 (+200) - users_controller を実装 (+49)
このような粒度でコミットが作られている場合、レビュアーはコミットを順番に読んでいくことで、まるで実装者の作業を追体験しているかのように PullRequest の内容を読み解いていけると思います。
この例では省略していますが、コミットログに付加的な情報が添えられていれば開発時に考えたことを残しておけば、より鮮明に見えてくるでしょう。
※ GitHub の場合、PullRequest の Commits
タブを開き、適当なコミットの詳細ページに進んだら「< Prev」と「Next >」ボタンを使って前後の Commit に移動できます。
我々開発者は、大きな課題に直面したとき、よく問題を小さな粒度に分解してから1つずつ取り掛かっていくと思います。
PullRequest のレビューにおいても同じで、修正内容全体としては大きかったとしても、それを構成するコミットがいい感じに分解されていれば、実装者の作業の流れや意図がわかりやすくなり、レビューする側のコストは下がっていくと考えています。
書籍において、著者の意図や考えが理解できる・想像できるときにスラスラ読んでいけると思いますが、それに近い感覚です。
また、この方法の良いところは、しっかりとレビューすべきポイントとそうでないところを取捨選択しやすくなるという点もあります。
上記の例で言うと bin/rails db:migrate を実行
のコミットについては自動生成された diff となるため、その前のコミットが問題無ければじっくり見る必要性は薄いでしょう。
一方で User の作成処理を実装
の部分は diff も大きく、また注目すべきポイントであることが見て取れるはずです。
知っていると便利な git のテクニック3選
今回例にあげたようなわかりやすい開発作業であれば特別なテクニックは不要ですが、現実的には当初思っていたように作業が進まないことも多いでしょう。
うっかり DB の制約を追加するのを忘れていたり、リンター・フォーマッターの実行を忘れていたり等、作業を進めている中で後から気がつくことも多いと思います。
そのようなコミットは数が少なければそれはそれでリアルな作業が追体験できて良いと思うのですが、数が増えてくると整理したくなってきます。そんなときに、私がよく使う3つのgitコマンドについて紹介します。
1つ前のコミットに混ぜ込む : git commit —amend
直前のコミットに追加し忘れていた修正がある場合、
$ git add <対象のファイルパス> $ git commit --amend
で混ぜ込むことができます。
この機能はシンプルでわかりやすく使っている方も多いのではないかと思います。
1つ以上前のコミットに混ぜ込む : git commit —fixup
直前ではないコミットに追加し忘れていた修正がある場合は git commit —fixup
が使えます。この機能はざっくり2ステップに分かれます。
まず git commit —fixup
で混ぜ込みたいコミットのハッシュを渡します。
$ git commit --fixup <混ぜたいコミットのハッシュ値>
すると fixup! <混ぜたいコミットのコミットメッセージ>
というメッセージの新しいコミットが作られます。この時点ではただコミットが増えただけの状態です。
この後に git rebase -i —autosquash <混ぜたいコミットの1つ前のハッシュ>
を実行すると次のような画面でエディタが立ち上がります。
pick 783e434 ABC fixup 676869d fixup! ABC pick 07b47f5 DEF
お使いのエディタが Vim であれば :wq
などで保存して終了すれば完了です。
色々な改変ができる : git rebase -i
単に既存コミットに混ぜ込みたい以上にコミット履歴を変更したい場合は、
$ git rebase -i <変更したいコミットの1つ前のハッシュ>
を実行します。この機能の詳細な説明は省略しますが、自分がよく使う場面としては
- 既存のコミットのメッセージを変更したいとき
- コミットの順番を変更したいとき
- 既存の A と B のコミットを1つにしたいとき
などです。
機能が豊富なので、まずは自分の置かれた状況で必要になったケースの利用方法を1つずつ覚えていくのが良いのではないかと思います。
おわりに
以上、私が PullRequest を作るときにひっそりと行っているちょっとしたワークフローのご紹介でした。
これは、自分自身が過去にレビュアーとしてレビューをしたときに読みやすい PullRequest に出会い、そこで感銘を受けてそのときから実践しているものでした。
レビューしやすい PR を作ることに関心がある、どなたかの参考となれば幸いです。
株式会社hacomonoでは一緒に働く仲間を募集しています。
採用情報や採用ウィッシュリストもぜひご覧ください!