フェッチ、マージ、プルを使用してコードを更新する
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Visual Studio 2019 | Visual Studio 2022
プロジェクトに複数の共同作成者がいるときは、他のユーザーがプロジェクトのリモート リポジトリにアップロードした作業をダウンロードして統合することで、ローカルの Git リポジトリを最新の状態に保ちます。 次の Git コマンドで、ローカル リポジトリを更新します。
- Git "フェッチ" は、他のユーザーがリモート リポジトリにアップロードした新しいコミットをダウンロードします。 ローカル リポジトリ キャッシュ内のリモート追跡ブランチが更新されます。ローカル ブランチは変更されないままです。
- Git "マージ" は、1 つ以上のソース ブランチからのコミットをターゲット ブランチに統合します。
- Git "リベース" は、ソース ブランチからのコミットをターゲット ブランチに統合しますが、Git マージとは異なる方法を使用します。
- Git "プル" はフェッチの次にマージまたはリベースを実行して、フェッチされたコミットを現在のローカル ブランチに統合します。
Visual Studio は、ローカル リポジトリをリモート リポジトリと同期するときに、これらの Git コマンドのサブセットを使用します。
Git ワークフローの概要については、Azure Repos Git チュートリアル参照してください。
この記事では、次のタスクの手順を説明します。
- "フェッチ" を使用して変更をダウンロードする
- "マージ" または "リベース" を使用してブランチを更新する
- "プル" を使用して変更をダウンロードしブランチを更新する
フェッチを使用して変更をダウンロードする
Git フェッチは、ローカル リポジトリに存在しないリモート ブランチ コミットと参照ファイル オブジェクトをダウンロードし、ローカル リポジトリ キャッシュ内のリモート追跡ブランチを更新します。 リモート追跡ブランチは、ローカルにキャッシュされたリモート ブランチの読み取り専用コピーであり、ローカル ブランチではありません。 Git フェッチは、ローカル ブランチを更新しません。 たとえば、origin
によって指定されたリモート リポジトリに bugfix3
ブランチがある場合、Git フェッチはローカルの bugfix3
ブランチではなく origin/bugfix3
という名前のリモート追跡ブランチを更新します。 リモート追跡ブランチを使用すると、次のことができます。
- リモート追跡ブランチとローカル ブランチを比較して、フェッチされた変更を確認します。
- リモート追跡ブランチをローカル ブランチにマージします。
- リモート追跡ブランチから新しいローカル ブランチを作成します。
Visual Studio 2022 は、[Git] メニュー、[Git 変更]、および [ソリューション エクスプローラー] のコンテキスト メニューを使用して、Git バージョン管理エクスペリエンスを提供します。 Visual Studio 2019 バージョン 16.8 には、チーム エクスプローラーの Git ユーザー インターフェイスも用意されています。 詳細については、「Visual Studio 2019 - チーム エクスプローラー」タブを参照してください。
[Git 変更] ウィンドウで、[フェッチ] を選択します。 次に、[outgoing/incoming] (送信/受信) を選択して [Git リポジトリ] ウィンドウを開きます。
Git メニューから [フェッチ] を選択することもできます。
[Git リポジトリ] ウィンドウで、フェッチされたコミットが [受信中] セクションに表示されます。 フェッチされたコミットを選択して、そのコミット内の変更されたファイルの一覧を表示します。 変更されたファイルを選択して、変更された内容の差分ビューを表示します。
ヒント
フェッチは、リモートに対応するものがなくなったローカル リポジトリ キャッシュ内のリモート追跡ブランチを削除しません。 フェッチ中に古くなったリモート追跡ブランチを取り除くように Visual Studio を構成するには:
- [ツール]>[オプション]>[ソース管理]>[Git グローバル設定] の順に選択します。
- [フェッチ中にリモート ブランチを取り除く] オプションを
True
に設定します。
Git フェッチの後、ローカル ブランチを、それに対応するリモート追跡ブランチと比較して、リモート ブランチで何が変更されたかを確認できます。 フェッチされた変更を使用して現在のローカル ブランチを更新する場合は、Git マージまたはリベースを実行できます。 あるいは、Git フェッチと Git マージまたはリベースとを組み合わせた Git プルを実行できます。 Git マージと Git リベースの両方とも、ソース ブランチからのコミットを適用してターゲット ブランチを更新します。 ただし、Git マージと Git リベースは、異なる方法を使用します。 詳細については、「マージまたはリベースを使用してブランチを更新する」とリベースとマージの使い分けに関する記事を参照してください。
マージまたはリベースを使用してブランチを更新する
Git マージと Git リベースは、ソース ブランチからのコミットを現在のローカル ブランチ (ターゲット ブランチ) に統合します。 Git マージは、早送りまたは早送りなしのマージを実行します。 早送りなしのマージは、"3 方向" マージまたは "真の" マージとも呼ばれます。 Git リベース は別の種類のマージです。 これらのマージの種類を次の図に示します。
Git マージと Git リベースは、Git ワークフローで広く使用されています。 ローカルの機能またはバグ修正ブランチで作業するときは、次の方法が一般的です。
- リモート コミットのフェッチとマージを定期的にプルして、ローカルの
main
ブランチをリモートの対応するものと同じ状態に保ちます。 - リベースまたはマージを使用して、ローカルの
main
ブランチの更新内容をローカルの機能ブランチに統合します。 - ローカルの機能ブランチの作業を対応するリモート ブランチにプッシュして、バックアップします。
- 機能の完了時に、リモートの機能ブランチをリモートの
main
ブランチにマージする pull request を作成します。
この方法は、次の作業に役立ちます。
- 自分の作業に影響を与える可能性がある他のユーザーによる最近の作業を常に把握しておくこと。
- 自分の作業内容と他のユーザーとの間の競合を迅速に解決すること。
- 最新のプロジェクト内容に対して新しい機能を適用すること。
- 作業の pull request レビューを受けること。
マージ
Git マージでは、ターゲット ブランチの先端がソース ブランチ内に存在する場合、既定のマージの種類は早送りマージになります。 それ以外の場合、既定のマージの種類は早送りなしマージになります。
早送り Git マージでマージの競合が発生する可能性はありません。ターゲット ブランチの先端がソース ブランチから外れた場合、Git は早送りマージを適用しないためです。 既定では、Git は可能な限り早送りマージを使用します。 たとえば、リモートの対応するブランチからプルすることによってのみ更新するローカル ブランチに、Git は早送りマージを適用します。
早送りなし Git マージは、ソース ブランチの変更とターゲット ブランチの変更を統合する新しいターゲット ブランチ "マージ コミット" を生成します。 対象になる変更は、両方のブランチに共通する最後のコミットの後に行われた変更です。 前の図では、コミット C が両方のブランチの最後の共通コミットです。 いずれかのソース ブランチの変更がいずれかのターゲット ブランチの変更と競合する場合、Git はマージの競合を解決するように求めるメッセージを表示します。 マージ コミット (L) には、ソース ブランチとターゲット ブランチの変更を統合したものが含まれています。 ソース ブランチとターゲット ブランチの先端 (K と E) がマージ コミットの親です。 ブランチのコミット履歴では、マージ コミットはマージ操作に役立つマーカーであり、どのブランチがマージされたかを明確に示します。
Git マージはターゲット ブランチのみを変更します。ソース ブランチは変更されないままです。 1 つ以上のマージ競合が発生すると、マージを完了するにはそれらを解決する必要があります。 または、マージ操作を取り消して、ターゲット ブランチを以前の状態に戻すことができます。
マージ オプションと方法の詳細については、 Git リファレンス マニュアル と Git マージ方法に関するページを参照してください。
ヒント
ソース ブランチがリモート追跡ブランチの場合は、マージの前に Git フェッチを実行してブランチが最新になるようにします。
メニュー バーから [Git]>[ブランチの管理] を選択して、[Git リポジトリ] ウィンドウを開きます。
[Git リポジトリ] ウィンドウで、ターゲット ブランチを右クリックし、[チェックアウト] を選択します。
ソース ブランチを右クリックし、[<source-branch> を <target-branch> にマージする] を選択します。
マージが成功すると、Visual Studio が確認メッセージを表示します。
マージの競合が原因でマージが停止した場合、Visual Studio から通知されます。 競合を解決するか、マージを取り消してマージ前の状態に戻すことができます。
リベースする
Git リベースは、ターゲット ブランチのコミット履歴を再度シーケンス処理して、最後の共通コミット以降のすべてのソース ブランチ コミットを、それに続いてすべてのターゲット ブランチ コミットを格納します。 これについて別の見方をすると、Git リベースはソース ブランチの履歴に対してターゲット ブランチの変更を再現します。 いずれかのソース ブランチの変更がいずれかのターゲット ブランチの変更と競合する場合、Git はマージの競合を解決するように求めるメッセージを表示します。 Git リベースは、マージ コミットを作成しません。 注目点として、Git リベースは、既存のターゲット ブランチ コミットのシーケンスを変更します。これは、他のマージ方法では起こりません。 前の図では、コミット K' には K と同じ変更が含まれていますが、C ではなくコミット E がリンク元であるため、新しいコミット ID を持ちます。
Git リベースはターゲット ブランチのみを変更します。ソース ブランチは変更されないままです。 1 つ以上のマージ競合が発生すると、リベースを完了するにはそれらを解決する必要があります。 または、リベース操作を取り消して、ターゲット ブランチを以前の状態に戻すことができます。
機能またはバグ修正ブランチで作業している唯一のユーザーである場合は、新しい main
ブランチ コミットをそれに統合するために Git リベースを使用することを検討してください。 それ以外の場合は、Git マージを使用してください。 Git リベースとそれを使用する状況の詳細については、「リベースを使用して変更を適用する」と「リベース対マージ (英語)」を参照してください。
ヒント
ソース ブランチがリモート追跡ブランチの場合は、リベースの前に Git フェッチを実行してブランチが最新になるようにします。
[Git]>[ブランチの管理] を選択して、[Git リポジトリ] ウィンドウを開きます。
[Git リポジトリ] ウィンドウで、ターゲット ブランチを右クリックし、[チェックアウト] を選択します。
ソース ブランチを右クリックし、[<target-branch> を <source-branch> にリベースする] を選択します。
リベースが成功すると、Visual Studio が確認メッセージを表示します。
マージの競合が原因でリベースが停止した場合、Visual Studio から通知されます。 競合を解決するか、リベースを取り消してリベース前の状態に戻すことができます。
プルを使用して変更をダウンロードしブランチを更新する
既定では、Git プルは Git フェッチ と Git マージ を組み合わせて、リモートの対応するものから現在のローカル ブランチを更新します。 オプションで、Git プルは Git マージの代わりに Git リベースを実行できます。
Git フェッチとは異なり、Git プルは、リモート リポジトリから新しいコミットをダウンロードした直後に、現在のローカル ブランチを更新します。 Git フェッチの直後に現在のローカル ブランチを更新することがわかっているときは、Git プルを使用してください。
ヒント
プル時にマージではなくリベースするように Visual Studio を構成するには:
- [Git] メニューで、[ツール]>[オプション]>[ソース管理]>[Git グローバル設定] の順に移動します。
- [プルするときにローカル ブランチをリベースする] オプションを
True
に設定します。
[Git 変更] ウィンドウで、[プル] を選択します。
Git メニューから [プル] を選択することもできます。
プル操作が完了すると、確認メッセージが表示されます。
プル操作のマージ部分で競合が発生した場合、Visual Studio から通知されます。 競合を解決するか、マージを取り消してマージ前の状態に戻すことができます。
注意
Visual Studio では、同期はプルを、次にプッシュを実行して、ローカルとリモートのブランチを同期します。 同期の詳細については、「Visual Studio でバージョン コントロールに Git のフェッチ、プル、プッシュ、同期を使用する」を参照してください。