Skip to main content

プルリクエストのマージについて

フィーチャーブランチ内のすべてのコミットを保持したままプルリクエストをマージすることも、すべてのコミットを単一のコミットにまとめてからマージすることも、個々のコミットをブランチからブランチにリベースしてマージすることもできます。

コミットをマージする

pull request で既定の [pull request のマージ] オプションをクリックすると、機能ブランチからのすべてのコミットがマージ コミット内のベース ブランチに追加されます。 pull request は、--no-ff オプションを使用してマージされます。

pull request をマージするには、リポジトリの書き込みアクセス許可が必要です。

標準的なマージとコミットのフローの図。機能ブランチからのコミットと追加のマージ コミットの両方が "main" に追加されています。

コミットをスカッシュしてマージする

プルリクエストをスカッシュし、マージする際の要約を提供します。

squash マージのマージメッセージ

squash してマージすると、GitHub によって既定のコミット メッセージが生成されます。このメッセージは編集できます。 リポジトリの構成方法と pull request 内のコミット数 (マージ コミットを除く) にもよりますが、このメッセージには pull request のタイトル、pull request の説明、コミットに関する情報などが含まれます。

コミット数まとめ説明
単一のコミット単一のコミットのコミットメッセージのタイトルと、その後に続くプルリクエスト番号単一のコミットのコミットメッセージの本文テキスト
複数のコミットプルリクエストのタイトルと、その後に続くプルリクエスト番号squash されたすべてのコミットのコミットメッセージの日付順のリスト

リポジトリに対するメンテナまたは管理者のアクセス権を持つユーザーは、スカッシュされたすべてのコミットについて、pull request のタイトル、pull request のタイトルとコミットの詳細、または pull request のタイトルと説明を使うように、リポジトリの既定のマージ メッセージを構成できます。 詳しくは、「プルリクエストにコミットの圧縮を設定する」をご覧ください。

長時間にわたるブランチを squash してマージする

プルリクエストのマージ後もヘッドブランチで作業を続ける予定がある場合、プルリクエストをスカッシュとマージしないことをお勧めします。

pull request を作成すると、GitHub によって、ヘッド ブランチとベース ブランチの両方での最近のコミットが特定されます。共通の先祖のコミットです。 プルリクエストを squash してマージすると、GitHub は、共通の先祖のコミット以降に head ブランチで行ったすべての変更を含むコミットをベースブランチに作成します。

このコミットはベースブランチのみで行われ、head ブランチでは行われないため、2 つのブランチの共通の先祖は変更されません。 head ブランチで作業を続け、その後、2 つのブランチ間に新しいプルリクエストを作成すると、そのプルリクエストには、すべての共通祖先以降のコミットが含まれます。これには、前のプルリクエストでスカッシュしてマージしたコミットも含まれます。 コンフリクトがない場合は、これらのコミットを安全にマージできます。 ただし、このワークフローでは高確率でマージコンフリクトが発生します。 長時間にわたる head ブランチのプルリクエストを squash してマージし続ける場合は、同じコンフリクトを繰り返し解決する必要があります。

コミットをリベースしてマージする

pull request で [リベースとマージ] オプションを選択すると、トピック ブランチ (または head ブランチ) からのすべてのコミットが、マージ コミットなしに個別にベース ブランチに追加されます。 このように、リベースとマージの動作は、線形プロジェクト履歴を維持することで、早送りマージ に似ています。 しかし、リベースは、ベース ブランチのコミット履歴を新しいコミットで書き直すことでこれを実現します。

GitHub でのリベースとマージの動作は、git rebase とは少し異なっています。 GitHub でリベースしてマージすると、常にコミッター情報が更新され、新しいコミット SHA が作成されますが、GitHub 外の git rebase は、先祖コミットの上でリベースが発生した場合、コミッター情報は変更されません。 git rebase の詳細については、Git ドキュメントの「git-rebase」を参照してください。

pull request をリベースしてマージするには、リポジトリに書き込みアクセス許可が必要であり、リポジトリでリベース マージが許可されている必要があります。

git rebase の視覚的表現については、ProGit ブックの「GitBranching-Rebasing」の章を参照してください。

次の場合、自動的にリベースとマージを行うことはできません。

  • プルリクエストにマージコンフリクトがある。
  • ベースブランチからヘッドブランチへのコミットのリベースでコンフリクトが生じる。
  • たとえば、マージコンフリクトなしにリベースできるものの、マージとは異なる結果が生成されるような場合、コミットのリベースは「安全ではない」と考えられます。

それでもコミットをリベースしたいにもかかわらず、自動的にリベースとマージが行えない場合、次の操作を行う必要があります。

  • トピックブランチ (あるいは head ブランチ) をベースブランチにローカルでコマンドラインからリベースする
  •         [コマンド ラインでマージの競合を解決します](/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line)。
    
  • リベースされたコミットをプルリクエストのトピックブランチ(あるいはリモートの head ブランチ)に強制プッシュする。

リポジトリでの書き込みアクセス許可を持つすべてのユーザーは、[リベースとマージ] ボタンを使って変更をマージできます。

間接マージ

ヘッド ブランチが外部のベース ブランチに直接的または間接的にマージされている場合は、pull request を自動的にマージできます。 つまり、ヘッド ブランチのチップ コミットがターゲット ブランチのチップから到達可能になった場合です。 たとえば、次のように入力します。

  • ブランチ main はコミット C にあります。
  • ブランチ featuremain から分岐されており、現在コミット D にあります。このブランチには、main をターゲットとする pull request があります。
  • ブランチ feature_2feature から分岐されており、現在コミット E にあります。このブランチにも、main をターゲットとする pull request があります。

pull request E --> main が最初にマージされた場合、**** からのすべてのコミットが --> から到達できるようになったため、pull request mainfeature は "自動的" にマージ済みとしてマークされます。main コマンド ラインからの feature_2 への main のマージとサーバーへの main のプッシュにより、"両方の" pull request がマージ済みとしてマークされます。

間接マージが発生するのは、pull request のヘッド ブランチ内のコミットがリポジトリの既定のブランチに直接プッシュされる場合か、pull request のヘッド ブランチ内のコミットが別の pull request に存在し、 [マージ コミットの作成] オプションを使ってリポジトリの既定のブランチにマージされる場合のみです。

別の pull request のヘッド ブランチ内に存在するコミットを含む pull request が、 [スカッシュしてマージ] または [リベースしてマージ] オプションを使ってマージされた場合、ベース ブランチに新しいコミットが作成され、別の pull request は自動的にマージされません。

間接的にマージされたプルリクエストは、ブランチ保護ルールを満たしていない場合でも としてマークされます。

参考資料

  •         [AUTOTITLE](/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests)
    
  •         [AUTOTITLE](/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts)