Skip to content
This page has been auto-translated and may contain errors.View in English

プルリクエストのフロー

docs.scrimba.com

自分の独立したブランチで機能に取り組んでいて、それが完成しました。プロジェクトは共有されています。他の人もコミットしているため、mainに直接プッシュして運を天に任せることはしません。変更をレビューしてもらい、必要に応じて議論を交わし、チーム全体が認識できるようにマージしたいのです。マシン上のブランチからmainにコードが統合されるまでの全体的なプロセスがプルリクエストのフロー(pull request flow)です。これはGitHubのほぼすべてのチームが変更を統合する方法です。このGit側の処理は、前の章のコマンドだけを使います。ブランチ、コミット、そしてプッシュです:

bash
$ git switch -c add-five-day-forecast
Switched to a new branch 'add-five-day-forecast'
$ git add src/forecast.js
$ git commit -m "Add five-day forecast panel"
$ git push -u origin add-five-day-forecast
Branch 'add-five-day-forecast' set up to track 'origin/add-five-day-forecast'.

このプッシュはあなたのブランチをGitHubに送信します。まだ何もマージされていませんし、レビューのための提案も出ていません。次のステップ(プルリクエストを開くこと)はGitHubのウェブサイトで行われます。

プルリクエストを開くと何が起こるか

GitHubでは、上記のようなプッシュの後、通常、新しいブランチをmainと比較するオプションを提供するバナーが表示されます。それをクリックして、変更内容とその理由の短い説明を書いて、作成されたページを開きます。そのページが**プルリクエスト**です。しばしばPRと略されます:1つのブランチを別のブランチにマージする要求であり、その周辺で実施される継続的な会話が添付されています。

プルリクエストはマージを提案し、承認を待ちます。誰か、あるいはあなた自身またはチームメイトが変更内容を読み、コメントを残し、それが正しく見えるまでマージしません。それまでの間、あなたのブランチとmainは、ページを開く前とまったく同じままです。

機能が完成するまで待つ必要はなく、早期にPRを開くことができます。多くのチームは早期に開いてドラフトとしてマークします。これは「まだレビューの準備ができていない」を示しながら、レビュアーに仕事が完了する前に方向についてコメントする場所を与えます。良い説明は関連する問題にリンクし、テストした内容を記載するため、レビュアーがdiff だけからそれを再構築する必要がありません。

GitHubはPRのブランチをリポジトリに追加する前でさえ、すべてのプルリクエストのrefを保持します:refs/pull/<number>/head。それを直接フェッチして、最初にそれらのフォークをリモートとして追加することなく、チームメイトのPRをマシン上でチェックアウトします。

bash
$ git fetch origin pull/42/head:pr-42
From github.com:mara-chen/weather-app
 * [new ref]         refs/pull/42/head -> pr-42
$ git switch pr-42
Switched to branch 'pr-42'

これでpr-42はプルリクエスト番号42から構築された実際のローカルブランチであり、1つのコメントを残す前に実行とテストの準備ができています。

Junoプルリクエストを開くと何が起こるか プルリクエストはあなたのブランチを別のブランチにマージするための要求であり、プッシュ後にGitHubで開かれます。誰かが最初に変更をレビューし、その後でのみマージされます。日常のループはブランチ、プッシュ、プルリクエストを開く、レビューを受ける、マージです。
Junoプルリクエストを開くと何が起こるか PRはマージを提案し、その周囲の会話を保持します。ドラフトとして早期に開いて、作業が完了する前にフィードバックを取得できます。レビュアーが実際に読むように説明を書きましょう:何が変更されたか、なぜ、そして何をテストしたか。
Junoプルリクエストを開くと何が起こるか GitHubはすべてのプルリクエストの隠された ref refs/pull/<number>/head を保持しているため、フォークをリモートとして追加せずに git fetch origin pull/42/head:pr-42 でチームメイトのPRをマシン上に直接フェッチできます。最初のコメントを残す前にローカルで変更をテストしてください。

フォークとブランチ

ブランチからのプルリクエストを開くことは、リポジトリへの書き込みアクセス権がある場合に機能します。これは、自分のチームのプロジェクトでは通常のケースです。書き込みアクセス権がないプロジェクトに貢献するには、1つの追加ステップが必要です:フォーク(自分の GitHub アカウント下でのリポジトリの独自コピー)。

フォーク内でブランチ分けとコミットを行い、所有するプロジェクト内で行うのとまったく同じようにプッシュしてから、フォークのブランチから元のリポジトリへのプルリクエストを開きます。GitHubは2つのリポジトリ間で1つのリポジトリ内の2つのブランチを比較するのと同じ方法で比較するため、レビューとマージのフロー はどちらの方法でもまったく同じに見えます。

フォークしたプロジェクトに複数のPRを送信する予定がある場合、通常upstreamという名前の元のリポジトリを2番目のリモートとして追加する価値があります。originは独自のフォークを指し続けます。git fetch upstreamを実行して、upstream/mainをブランチにマージして、フォーク以降に進んだプロジェクトに追いつきます。リモートとGitHubの章がカバーしているのと同じステップを使用してあらゆるリモートで行います。

Junoフォークとブランチ リポジトリへの書き込みアクセス権がある場合は直接ブランチします。これはあなた自身のチームのプロジェクトです。書き込みアクセス権がない場合はフォークします:フォークは誰かの別のリポジトリのあなた自身のコピーであり、そのコピー内でブランチ分けとプッシュを行ってから、元のリポジトリへのプルリクエストを開きます。
Junoフォークとブランチ フォークはあなたのアカウント下の完全なリポジトリのコピーであり、書き込みアクセス権がない場所に貢献するために使用されます。フォーク内でブランチ分け、コミット、プッシュを通常どおり行います。GitHubはフォークのブランチを元のリポジトリと比較し、1つのプロジェクト内の2つのブランチを比較するのと同じ方法で比較します。
Junoフォークとブランチ フォークされたプロジェクトでは2つのリモートを保つ:originは独自のフォーク用、upstreamは元のリポジトリ用です。進むにつれてその変更をフェッチしてマージできるようにします。PR自体は依然としてフォークのブランチを元のリポジトリのベースブランチと比較します。

プルリクエストをレビュー完了まで進める

PRが開かれると、diffについての実行中の会話になります。レビュアーが変更を読み、特定の行にコメントを残し、承認または変更リクエストを行います。変更が要求されたら、同じブランチへのコミットとプッシュを続けます:すべてのプッシュは同じPRを更新し、新しいものは作成しません。レビュアーが承認し、必要なチェックがすべてパスしたら、PRはマージの準備ができています。

GitHubはレビューを3つの状態の1つとして追跡します。承認、変更リクエスト、またはコメント(どちらかの判定なしのフィードバック)。コメントに返信してそれらに対応し、会話を解決とマークして、レビュアーが一目でどのような状態が残っているかを確認できるようにします。特定のコメント用の修正をプッシュする場合、コミットメッセージまたは返信でそれを述べるのに役立ちます。長いPRを調べるレビュアーは正確にそれをスキャンしているため です。

PRが必要とする承認の数、およびすべてのコメントスレッドをマージボタンを解除する前に解決済みとしてマークする必要があるかどうかは、通常、適切に実行されるプロジェクトではベースブランチ自体に付属するルールです。

Junoプルリクエストをレビュー完了まで進める レビュアーがあなたのプルリクエストにコメントして、変更をリクエストする可能性があります。変更に対応するために同じブランチへのコミットとプッシュを続けます。PRは自動的に更新されます。誰かが承認したらマージが行われます。
Junoプルリクエストをレビュー完了まで進める レビューは3つの状態の1つで着地します:承認、変更リクエスト、またはコメント。同じブランチへの修正をプッシュしてPRを更新して、対応するコメントに返信して、長いスレッドでレビュアーの方向を維持します。
Junoプルリクエストをレビュー完了まで進める レビュー状態はマージボタンのロック解除の有無を決定しますが、正確なバー、必要な承認の数、すべてのコメントスレッドが解決される必要があるかどうかは、通常、適切に実行されるプロジェクトではベースブランチ自体に付属するルールです。

プルリクエストがマージできない理由

PR上のマージボタンが グレーアウトされることがあり、GitHubはその代わりにメッセージを表示します:「このブランチは解決する必要がある競合があります」または「このブランチはベースブランチより古い状態です」。両方のメッセージは通常の修正可能な状態を説明しています:ブランチを作成した後、mainが前に進みました。通常、それは誰か他のPRがその間にマージされたためです。あなたのブランチはGitHubが2つをクリーンに組み合わせることができる前に追いつく必要があります。これはプロジェクトが複数の貢献者を持つあらゆるプロジェクトで起こるので、それを恐れるのではなく予想してください。

ローカルで2つのブランチをまとめるのと同じ方法で修正してください:

bash
$ git switch add-five-day-forecast
$ git fetch origin
From github.com:mara-chen/weather-app
   9f8e7d6..b7c9e21  main       -> origin/main
$ git merge origin/main

重複がない場合、マージはそれ自体で完了し、プッシュして、PRは更新され、ボタンのロックが解除されます。同じ行が両側で変更された場合、Gitは競合をファイルにマークして、マージと競合で説明されているのと同じように正確に解決します。ファイルを開き、競合マーカーを希望の結果に編集してから、git addgit commitでマージを終了し、再度プッシュします。

スタックされたプルリクエストは追いつくか、その競合を解決する必要があります。

1日か2日以上開いたままのPRでは、ボタンがブロックされるまで待つのではなく、mainをブランチに時々マージするのは価値があります。1日古いブランチは通常、競合なしでマージされます。3週間古いブランチは、2つの変更が同じ行に衝突するための表面がはるかに多くあります。GitHubの独自の「Update branch」ボタンPRページ上のは、手で解決するものがない場合、これと同じマージをあなたのためにします。

一部のチームは機能ブランチをmainにリベースしてマージの代わりに、すべてのPRのマージコミットを表示するのではなく、最終的な履歴を線形に保つためです。そのトレードオフはマージと競合で説明されているのと同じです:リベースはブランチのコミットを書き直します。これはあなたが唯一のコピーを持っているので安全です。そのため、マシン上にのみ存在し、そのPRは合理的な候補です。他の人が既にプッシュして構築したブランチをリベースすることはできません。その上に、それは彼らが頼っている履歴を書き直すため です。

Junoプルリクエストがマージできない理由 グレーアウトされたマージボタンは、ブランチがmainの後ろにあるか、競合があることを意味します。何も破損していません。ブランチに切り替えて、フェッチして、mainをマージします。他の場所と同じように競合を解決してから、再度プッシュします。
Junoプルリクエストがマージできない理由 GitHubがマージボタンをブロックするまで待つのではなく、長期実行のブランチにmainを時々マージします。より小さく、より頻繁なキャッチアップは、より小さな競合を意味し、GitHubの「Update branch」ボタンは競合なしのケースをあなたのために行うことができます。
Junoプルリクエストがマージできない理由main上にブランチをマージまたはリベースすることの両方がスタックされたPRを修正し、ソロ機能ブランチはコミットのコピーを持つ人がいないため、リベースするのは安全です。他の人がブランチをプルしたら、代わりにマージするのを支持します。

プルリクエストの内部での仕組み

プルリクエストはGitオブジェクトではなく、そしてそれを作成する git コマンドはありません。GitとGitHubは同じものではありません:Gitはコミット、ブランチ、およびその他の refs(refはコミットを指す名前)についてのみ知っています。GitHubはPRページ全体、コメント、およびマージボタンを構築します。比較する2つのrefsの上に:あなたのブランチ(head)と、あなたがマージしているブランチ(base、通常はmain)。その比較が理由で、GitHubのウェブサイト(またはGitHub独自のコマンドラインツールやAPI経由)でプルリクエストを開き、平文gitコマンドでは開きません。

PRはGitHubに存在し、リポジトリの履歴から分離されているため、そのコメントとレビュー会話はコミットと一緒に移動しません。プロジェクトを別のホストに移動する場合、すべてのコミットは変更されずに移動します。しかし、プルリクエストとそれらの議論はGitHub上に留まります。彼らはそれ以来、Gitデータの一部ではなかったため です。

GitHubはマージベース(head refとbase refが共有する最新のコミット)を見つけることで、PRのdiffを計算してから、mainが今どのように見えるかに対してではなく、その点に対してheadと比較します。ブランチへのすべてのプッシュは、新しい比較を作成するのではなく、同じPRに新しいバージョンを追加します。**ブランチ保護**はこれすべての上に座っているポリシーレイヤーです:あなた(またはあなたの組織)がブランチに付属するルール。ほとんどの場合、mainは、ステータスチェックの合格を要求し、承認レビューセットの数を要求し、直接プッシュをブロックできるため、すべての変更がプルリクエストを強制されます。Gitそれ自体はこれのいずれも強制しません。これにより、ターミナルから直接mainにプッシュできます。GitHubのルールが要求を拒否するまで右上。

Junoプルリクエストの内部での仕組み プルリクエストはGitの上に重ねられたGitHubの機能です:Gitはコミットとブランチを追跡し、GitHubはPRページとマージボタンを追加することで2つを比較します。GitとGitHubを頭の中で分けておくと、他の方法では魔法のように見えるものの多くが説明されます。
Junoプルリクエストの内部での仕組み PRはブランチをベースブランチと比較し、完全にGitHub上で存在します。そのため、リポジトリがホストを変更した場合、そのコメントとレビュー履歴は移動しません。コミット自体は本当にGitの一部です。
Junoプルリクエストの内部での仕組み PRはGitHubを比較しており、共有マージベースから head ref を base ref と比較し、すべてのプッシュで更新されています。ブランチ保護はその上に強制されたポリシーです。マージ前にチェックまたはレビューを要求します。Gitそれ自体はこれのいずれも強制しません:GitHubのルールがそれを停止するまで、mainに直接プッシュさせます。