正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

リベースしてマージコンフリクトを解決する

Gitリベースは、コミットをターゲットブランチの先端に移動することで、1つのブランチから別のブランチへの変更を統合します。この操作の特徴:

  • ターゲットブランチからの最新のコードを使ってブランチを更新します。
  • デバッグとコードレビューを容易にするため、クリーンで直線的なコミット履歴を保持します。
  • 競合解決のために、コミットレベルでマージコンフリクトを解決します。
  • コード変更の時系列順序を保持します。

リベースを実行すると:

  1. 最初にブランチを作成した後、Gitがターゲットブランチに送信されたすべてのコミットをインポートします。

  2. Gitは、インポートされたコミットの上に、ブランチからのコミットを適用します。この例では、featureという名前のブランチが作成された後(オレンジ色)、main(紫色)からの4つのコミットがfeatureブランチにインポートされます。

    Gitリベースの図

ほとんどのリベースはmainに対して実行されますが、他のブランチに対してもリベースできます。別のリモートリポジトリを指定することもできます。たとえば、originの代わりにupstreamを指定します。

git rebaseはコミット履歴を書き換えます。共有ブランチで競合が発生し、複雑なマージコンフリクトが発生する可能性があります。デフォルトブランチに対してブランチをリベースする代わりに、git pull origin masterの使用を検討してください。プルすると、他のユーザーの作業を損なうリスクを軽減しながら、同様の効果が得られます。

リベース

Gitを使用してリベースを行うと、各コミットがブランチに適用されます。マージコンフリクトが発生すると、それらに対処するように求めるプロンプトが表示されます。

コミットのより高度なオプションについては、インタラクティブなリベースを使用してください。

前提要件:

  • ブランチに強制プッシュするには、権限が必要です。

Gitを使用してターゲットブランチに対してブランチをリベースするには:

  1. ターミナルを開き、プロジェクトディレクトリに変更します。

  2. ターゲットブランチのコンテンツが最新であることを確認してください。この例で、ターゲットブランチはmainです。

    git fetch origin main
  3. ブランチをチェックアウトします。

    git checkout my-branch
  4. オプション。ブランチのバックアップを作成します。

    git branch my-branch-backup

    バックアップブランチから復元した場合、この時点以降にmy-branchに追加された変更は失われます。

  5. mainブランチに対してリベースを行います。

    git rebase origin/main
  6. マージコンフリクトが存在する場合:

    1. エディタで競合を解決します。

    2. 変更をステージングします。

      git add .
    3. リベースを続行します。

      git rebase --continue
  7. 他のユーザーのコミットを保護しながら、変更をターゲットブランチに強制プッシュします。

    git push origin my-branch --force-with-lease

インタラクティブなリベース

インタラクティブなリベースを使用して、各コミットの処理方法を指定します。次の手順では、Vimテキストエディタを使用してコミットを編集します。

インタラクティブにリベースを行うには:

  1. ターミナルを開き、プロジェクトディレクトリに変更します。

  2. ターゲットブランチのコンテンツが最新であることを確認してください。この例で、ターゲットブランチはmainです。

    git fetch origin main
  3. ブランチをチェックアウトします。

    git checkout my-branch
  4. オプション。ブランチのバックアップを作成します。

    git branch my-branch-backup

    バックアップブランチから復元した場合、この時点以降にmy-branchに追加された変更は失われます。

  5. GitLab UIを使用し、マージリクエストのコミットタブで、リベースを行うコミットの数を確認します。

  6. これらのコミットを開きます。たとえば、最後の5つのコミットを編集するには:

    git rebase -i HEAD~5

    Gitは、ターミナルのテキストエディタで、最も古いコミットから順に開きます。各コミットには、実行するアクション、SHA、コミットタイトルが表示されます。例は次のとおりです。

    pick 111111111111 Second round of structural revisions
    pick 222222222222 Update inbound link to this changed page
    pick 333333333333 Shifts from H4 to H3
    pick 444444444444 Adds revisions from editorial
    pick 555555555555 Revisions continue to build the concept part out
    
    # Rebase 111111111111..222222222222 onto zzzzzzzzzzzz (5 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
  7. iを押して、Vimの編集モードに切り替えます。

  8. 矢印キーを使用して、編集するコミットにカーソルを移動します。

  9. 最初のコミット以外の各コミットで、picksquashまたはfixup(またはsまたはf)に変更します。

  10. 残りのコミットに対して操作を繰り返します。

  11. 編集モードを終了し、保存して終了します。

    • ESCを押します。
    • :wqと入力します。
  12. スカッシュすると、Gitにはコミットメッセージを編集するように求めるプロンプトが表示されます。

    • #で始まる行は無視され、コミットメッセージには含まれません。
    • 現在のメッセージを保持するには、:wqと入力します。
    • コミットメッセージを編集するには、編集モードに切り替え、変更して保存します。
  13. 変更をターゲットブランチにプッシュします。

    • リベースする前にコミットをターゲットブランチにプッシュしなかった場合:

      git push origin my-branch
    • 既にコミットをプッシュした場合:

      git push origin my-branch --force-with-lease

      一部の操作では、ブランチに変更を加えるためには強制プッシュが必要です。詳細については、リモートブランチへ強制プッシュするを参照してください。

コマンドラインから競合を解決する

各変更の制御を最大限にするには、GitLabではなく、コマンドラインからローカルで複雑な競合を修正する必要があります。

前提要件:

  • ブランチに強制プッシュするには、権限が必要です。
  1. ターミナルを開き、フィーチャーブランチをチェックアウトします。

    git switch my-feature-branch
  2. ターゲットブランチに対してブランチをリベースします。この例で、ターゲットブランチはmainです。

    git fetch
    git rebase origin/main
  3. 優先コードエディタで、競合するファイルを開きます。

  4. 競合ブロックを見つけて解決します。

    1. 保持するバージョン(=======の前または後)を選択します。
    2. 保持しないバージョンを削除します。
    3. 競合マーカーを削除します。
  5. ファイルを保存します。

  6. 競合のある各ファイルに対してプロセスを繰り返します。

  7. 変更をステージングします。

    git add .
  8. 変更をコミットします。

    git commit -m "Resolve merge conflicts"

    git rebase --abortを実行すると、この時点より前にプロセスを停止できます。Gitはリベースを中断し、ブランチをgit rebaseを実行する前の状態にロールバックします。git rebase --continueの実行後は、リベースを中断できません。

  9. リベースを続行します。

    git rebase --continue
  10. 変更をリモートブランチへ強制プッシュします。

    git push origin my-feature-branch --force-with-lease

リモートブランチへ強制プッシュする

コミットのスカッシュ、ブランチのリセット、リベースなどの複雑なGit操作を行うと、ブランチ履歴が書き換えられます。Gitでは、これらの変更を強制更新する必要があります。

共有ブランチでの強制プッシュは推奨されません。他のユーザーの変更を削除するリスクがあります。

ブランチが保護されている場合、次のいずれかを行わないと、強制プッシュすることはできません。

  • 保護を解除する
  • 強制プッシュを許可する

詳細については、保護されたブランチで強制プッシュを許可するを参照してください。

バックアップされたブランチを復元する

リベースまたは強制プッシュが失敗した場合は、バックアップからブランチを復元します。

  1. 正しいブランチにいることを確認します。

    git checkout my-branch
  2. ブランチをバックアップにリセットします。

    git reset --hard my-branch-backup

リベース後の承認

ブランチをリベースした場合、コミットが追加されています。プロジェクトがコミットを追加したユーザーによる承認を防止するように設定されている場合、リベースしたマージリクエストを承認することはできません。また、以前はコミッターであり、以前は承認できなかったユーザーが、変更を承認できるようになる場合があります。

さらに、承認してからリベースを実行したユーザーは、マージリクエストを承認したと表示される場合があります。ただし、ユーザーの承認は、マージリクエストに必要な承認数にはカウントされません。

トラブルシューティング

CI/CDパイプラインのトラブルシューティング情報については、CI/CDパイプラインのデバッグを参照してください。

/rebaseクイックアクション後のUnmergeable state

/rebaseコマンドはバックグラウンドタスクをスケジュールします。タスクは、ソースブランチの変更をターゲットブランチの最新のコミットにリベースしようとします。/rebaseクイックアクションを使用後にこのエラーが表示された場合は、リベースをスケジュールできません。

This merge request is currently in an unmergeable state, and cannot be rebased.

このエラーは、次のいずれかの条件に当てはまる場合に発生します。

  • ソースブランチとターゲットブランチの間に競合があります。
  • ソースブランチにコミットが含まれていません。
  • ソースブランチまたはターゲットブランチが存在しません。
  • エラーが発生し、差分が生成されませんでした。

unmergeable stateエラーを解決するには:

  1. マージコンフリクトを解決します。
  2. ソースブランチが存在し、コミットがあることを確認します。
  3. ターゲットブランチが存在することを確認します。
  4. 差分が生成済みであることを確認します。

/rebaseの後に無視される/mergeクイックアクション

/rebaseが使用されている場合、リベースの前にソースブランチがマージまたは削除される競合状態を回避するために、/mergeは無視されます。