KINTO Tech Blog
Development

GitHubでのPull Requestのオプション指定と罠

Cover Image for GitHubでのPull Requestのオプション指定と罠

この記事は KINTO テクノロジーズアドベントカレンダー 2024 の 13 日目の記事です 🎅🎄

はじめに

こんにちは。KINTO ONE開発部の新車サブスク開発グループでフロントエンド開発を担当しているITOYUです。

エンジニアの皆さん、GitHub を使っていますか?我々 KINTO テクノロジーズでも GitHub を利用しています。
チーム開発をする上で Pull Request 機能を使ってコードレビューとマージを行っています。

マージの実行時にオプション指定をすることが出来るのですが、オプション指定をすることが出来るのをご存知でしょうか?
各オプションの違いの説明と、私が過去に躓いた罠について説明します。

option_select

何を説明するのか

  • GitHub 上での Pull Request のマージオプション
    • Create a merge commit
    • Squash and merge
    • Rebase and merge
    • Rebase and mergegit rebaseは一緒じゃない
    • 自分が前に実行したオプションが次回のデフォルトになる

前提

  • develop ブランチと feature ブランチが存在している

  • develop ブランチから feature ブランチを切って作業をして、develop ブランチに対して Pull Request を作成する

  • develop ブランチと feature ブランチのコミット履歴は以下のようになっている

develop ブランチの commit 履歴
develop_history

feature ブランチの commit 履歴
feature_history

GitHub 上での Pull Request のマージオプション

Create a merge commit

Create a merge commit は、feature ブランチのコミットを hash 値を保持したまま develop ブランチにマージした後、新たにマージコミットを作成します。
実際にマージを行うと以下のようなコミット履歴になります。

マージ後の develop ブランチの commit 履歴
create_merge_commit

hash 値が保持されたまま develop ブランチにマージされていることが確認できます。そして新たにマージコミットが作成されていることが確認できます。

特徴

  • マージ元のコミット履歴の hash 値が保持される
  • マージコミットが作成されることでマージによる形跡が残る

使用例

  • 複数のコミットをそのまま保持したい場合
  • マージの履歴を明確に残したい場合

Squash and merge

Squash and merge は、feature ブランチのコミットを 1 つのコミットにまとめて develop ブランチにマージします。
実際にマージを行うと以下のようなコミット履歴になります。

マージ後の develop ブランチの commit 履歴
squash_and_merge

feature ブランチでは複数の commit がありましたが、develop ブランチには 1 つの commit しか存在していません。

特徴

  • マージ元のコミット履歴が1つにまとめられる

使用例

  • コミット履歴をシンプルに保ちたい場合
  • 小さな変更をまとめて1つのコミットにしたい場合

Rebase and merge

Rebase and merge は、feature ブランチのコミットを develop ブランチの最新のコミットの直後にコピーし、develop ブランチにマージします。
その際コミットはまとめられず、feature ブランチのコミット履歴がそのまま develop ブランチにマージされます。

マージ後の develop ブランチの commit 履歴
rebase_and_merge

この際マージコミットが作成されていないことが確認できます。

特徴

  • マージ元のコミット履歴がそのまま develop ブランチにマージされる
  • マージコミットが作成されないので、コミット履歴が綺麗になる
  • マージ元の hash 値とは異なり、新たなコミットとして作成される

使用例

  • コミット履歴をそのまま保持しつつ、マージコミットを作成したくない場合
  • リベースを行ってコミット履歴を整理したい場合

上記では各オプションの説明をしました。ここからは私が過去に躓いた罠について説明します。

Rebase and mergegit rebaseは一緒じゃない

中規模プロジェクト用の開発ブランチを用意して共同で開発をしていました。
そこでブランチ元のdevelopブランチが更新されたのでプロジェクト用のブランチをgit rebaseを利用してコミット履歴を整理しようと考えました。
ただそうなるとforce pushが必要になるので、共同で作業しているブランチにはforce pushを避けたいと考えました。

そこでGitHub PullRequest機能のオプションのRebase and mergeを使えば代用可能なのではないかと考えました。
そうすることでコミット履歴も綺麗に保たれ、ローカルでの作業もなくなり安全だと考えました。
さて、develop ブランチに feature ブランチから出した Pull Request をRebase and mergeオプションを使ってマージを行った後、差分が無いかチェックして見ました。
after_rebase

めちゃくちゃ差分がありました。

一見 develop ブランチと feature ブランチのコミット履歴は同じに見えますが、hash 値が異なっていました。
rebase_compare

Rebase and mergeの特徴の1つに「マージ元の hash 値とは異なり、新たなコミットとして作成される」というものがあるためです。

Rebase and mergeを実行した時とgit rebaseを実行した時には挙動が異なるので、同一の挙動を期待してはいけないと学びました。

自分が前に実行したオプションが次回のデフォルトになる

これは罠というか、不注意によるミスです。
前提として、私のチームではいつもSquash and mergeを利用して作業ブランチのコミット履歴を綺麗に保っています。

先ほどRebase and mergeによる実験をして失敗に終わった後、通常の作業に戻りました。
そして私の出した Pull Request が approve されたのでいつも通りマージを行いました。

そこで気付く違和感。何かがおかしい。

なぜかRebase and mergeが実行されている...

Pull Request のマージオプションは、自分が前に実行したオプションが次回のデフォルトになるようです。ちょっと考えれば当たり前のことですね。
今まで意識していなかったので気付かなかったのですが、オプションをいじる際は次の Pull Request にも影響があるので注意が必要だと学びました。

まとめ

GitHubのPull Requestマージ時のオプション指定の特徴を踏まえた上で、目的に合わせて適切なオプションを選択することが重要です。
私は以下のような使い分けをしています。

  • Create a merge commit: マージ元のコミットハッシュを保持し、マージの履歴を明確に残したい場合に使用します。これにより、どのブランチがどのタイミングでマージされたかが一目でわかります。
  • Squash and merge: 作業コミットを1つにまとめて、コミット履歴をシンプルに保ちたい場合に使用します。これにより、細かいコミットが1つにまとめられ、履歴が見やすくなります。
  • Rebase and merge: マージコミットを作成せずに、コミット履歴を直線的に保ちたい場合に使用します。これにより、変更の流れが追いやすくなり、履歴が綺麗になります。

また、Pull Requestをマージする際には、今設定されているオプションが何なのかを必ず確認してからマージを行うことで予期せぬ事故を防ぐようにしましょう。

Facebook

関連記事 | Related Posts

We are hiring!

【フロントエンドエンジニア(コンテンツ開発)】新車サブスク開発G/東京

新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。​業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、クルマのサブスクリプションサービス『KINTO ONE』のWebサイトコンテンツの開発・運用業務を担っていただきます。

【フロントエンドエンジニア】新車サブスク開発G/東京

新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。​業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、TOYOTAのクルマのサブスクリプションサービス『KINTO ONE』のWebサイトの開発、運用を行っていただきます。