rebase を使用して変更を適用する

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Visual Studio 2019 | Visual Studio 2022

Git では、新しいコミットのたびにその前任者にリンクすることで、ブランチでの開発履歴が自動的に保持されます。 あるブランチを別のブランチにマージすると、履歴の単純さが低下する可能性があります。 たとえば、早送りなしのマージでは、複数の先行処理を含むマージ コミットを作成することで、多様な開発行が結合されます。 逆に、Git リベースでは、マージ コミットを作成せずに多様な開発行を結合することにより、コミット履歴が単純になりますが、マージに関する情報は失われます。 マージの種類の選択は、マージの記録を保持するか、コミット履歴を簡略化するかによって影響を受ける可能性があります。

この記事では、早送りなしのマージではなくリベースを使用すべき状況について説明し、次のタスクの手順を示します。

  • ローカル ブランチのリベース
  • リベース後にローカル ブランチを強制的にプッシュする
  • ローカル コミットをスカッシュするための対話型リベース

Git ワークフローの概要については、Azure Repos Git チュートリアル参照してください。

ローカル ブランチのリベース

Git リベースでは、ソース ブランチからのコミットを現在のローカル ブランチ (ターゲット ブランチ) に統合します。 ソース ブランチは変更されません。 比較のために、Git リベースとその他のマージの種類を次の図に示します。

Git リベースを使用するときのコミットの前後を示す図。

Git リベースでは、ターゲット ブランチのコミット履歴を並べ替え、すべてのソース ブランチ コミットに続き、最後の共通コミット以降のすべてのターゲット ブランチ コミットが格納されます。 これについて別の見方をすると、リベースでは、ソース ブランチの履歴上でターゲット ブランチの変更が再現されます。 注目点として、Git リベースでは、既存のターゲット ブランチ コミットのシーケンスが変更されます。これは、他のマージ方法では起こりません。 前の図では、コミット K' には K と同じ変更が含まれていますが、C ではなくコミット E がリンク元であるため、新しいコミット ID が付けられます。

リベース中に、ソース ブランチの変更がいずれかのターゲット ブランチの変更と競合する場合、Git ではマージの競合を解決することを求めるメッセージが表示されます。 マージ中にマージ競合を解決するのと同じ方法で、リベース中にマージ競合を解決できます。

リベースと早送りなしのマージ

Git リベースは、早送りなしのマージ ("3 方向" または "真の" マージとも呼ばれる) に比べて結果は単純になりますが、コミット履歴の正確さは低下します。 コミット履歴にマージの記録が必要な場合は、早送りなしのマージを使用します。

機能ブランチまたはバグ修正ブランチで作業しているユーザーが自分だけの場合は、リベースを使用して、最近の main ブランチの作業をそれに定期的に統合することを検討してください。 この戦略は、他のユーザーによる最近の作業を把握し、発生したマージ競合を迅速に解決するのに役立ちます。 リベースすることで、自分の新しい機能を最新の main ブランチ作業の上に実装し、直線的なコミット履歴を維持するのに役立ちます。

Git リベースの詳細と、それを使用する状況については、「リベースとマージ」を参照してください。

リベースと強制プッシュのガイドライン

以前プッシュしたローカル ブランチをリベースし、既定の Git プッシュ コマンドをもう一度実行すると、プッシュは失敗します。 既定の Git プッシュ コマンドでは、早送りマージを適用して、ローカル ブランチをリモート ブランチに統合します。 このコマンドはリベース後に失敗します。これは、リベースによってローカル ターゲット ブランチ内の既存のコミットのシーケンスが変更されるため、リモート ターゲット ブランチの履歴と一致しなくなるためです。 このシナリオでは、リモート ブランチを上書きすることで、強制プッシュが成功します。

Git リベースと強制プッシュは強力なツールですが、使用するかどうかを決定するときは、次のガイドラインに留意してください。

  • 共有ブランチを誰も使用していないことが確かな場合を除き、プッシュされて他のユーザーと共有されているローカル ブランチをリベースしないでください。 リベースした後、ローカル ブランチはリモートブランチの履歴と一致しなくなります。
  • 他のユーザーが使用しているリモート ブランチに強制プッシュしないでください。そのリモート ブランチのローカル バージョンが、更新されたリモート ブランチ履歴と一致しなくなるためです。
  • リベースと強制プッシュの使用シナリオにチームが同意する必要があります。

ヒント

協調的レビュー プロセスの場合は、pull request を使用して、リモート リポジトリの既定のブランチに新しい作業をマージします。

リベースする方法

Visual Studio 2022 は、[Git] メニュー、[Git 変更]、および [ソリューション エクスプローラー] のコンテキスト メニューを使用して、Git バージョン管理エクスペリエンスを提供します。 Visual Studio 2019 バージョン 16.8 には、チーム エクスプローラーの Git ユーザー インターフェイスも用意されています。 詳細については、「Visual Studio 2019 - チーム エクスプローラー」タブを参照してください。

  1. [Git]>[ブランチの管理] を選択して、[Git リポジトリ] ウィンドウを開きます。

    Visual Studio の Git メニューの [ブランチの管理] オプションのスクリーンショット。

  2. [Git リポジトリ] ウィンドウで、ターゲット ブランチを右クリックし、[チェックアウト] を選択します。

    Visual Studio の [Git リポジトリ] ウィンドウのブランチ コンテキスト メニューにある [チェックアウト] オプションのスクリーンショット。

  3. ソース ブランチを右クリックし、[<target-branch> を <source-branch> にリベースする] を選択します。

    Visual Studio の [Git リポジトリ] ウィンドウのブランチ コンテキスト メニューにある [リベース] オプションのスクリーンショット。

  4. リベースが成功すると、Visual Studio が確認メッセージを表示します。

    Visual Studio の [Git リポジトリ] ウィンドウのリベース確認メッセージのスクリーンショット。

    マージの競合が原因でリベースが停止した場合、Visual Studio から通知されます。 競合を解決するか、リベースを取り消してリベース前の状態に戻すことができます。

    Visual Studio の [Git リポジトリ] ウィンドウのリベース競合メッセージのスクリーンショット。

リベース後にローカル ブランチを強制的にプッシュする

以前プッシュしたローカル ブランチをリベースすると、後続の既定の Git プッシュは失敗します。 代わりに、ローカル ブランチを強制プッシュして、対応するリモート ブランチを上書きし、コミット履歴が一致するようにすることができます。

警告

他のユーザーが作業しているブランチを強制プッシュしないでください。 詳細については、「リベースと強制プッシュのガイドライン」を参照してください。

Visual Studio で強制プッシュを実行するには、最初に強制プッシュ オプションを有効にする必要があります。

  1. [ツール]>[オプション]>[ソース管理]>[Git グローバル設定] の順に移動します。

  2. [push --force-with-lease を有効にする] オプションを選択します。

Git push --force-with-lease フラグは --force フラグよりも安全です。これは、強制プッシュするローカル ブランチ内で統合されないコミットを持つリモート ブランチを上書きしないためです。

  1. [Git 変更] ウィンドウで、プッシュ ボタンを選択してコミットをプッシュします。

    Visual Studio の [Git 変更] ウィンドウにある上矢印のプッシュ ボタンのスクリーンショット。

    または、[Git] メニューから [プッシュ] を選択することもできます。

    Visual Studio の [Git] メニューの [プッシュ] オプションのスクリーンショット。

  2. 既定の Git プッシュ操作が失敗した場合、Visual Studio では [Git - プッシュに失敗しました] ダイアログが起動します。 [強制プッシュ] を選択します。

    Visual Studio の [Git - プッシュに失敗しました] ダイアログのスクリーンショット。

  3. プッシュが成功すると、Visual Studio が確認メッセージを表示します。

    Visual Studio のプッシュ確認メッセージのスクリーンショット。

ローカル コミットをスカッシュするための対話型リベース

通常、ローカル機能ブランチで新しい機能について作業する場合は、複数のコミットを作成します。 新しい機能を発行する準備ができたら、それらのコミットを 1 つのコミットに統合してコミット履歴を簡略化することができます。 対話型リベースを使用して、複数のコミットを 1 つのコミットに "スカッシュ" できます。

Visual Studio 2022 では、対話型リベースはサポートされていません。 代わりに Git コマンド ラインを使用してください。

Note

Azure DevOps ユーザーはマージをスカッシュして、pull request 中にトピック ブランチのコミット履歴を要約できます。

次のステップ