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

Gitでの変更のチェリーピック

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

git cherry-pickをコマンドラインから使用すると、既存のブランチから現在のブランチに特定の変更がコピーされます。チェリーピックは、次のような場合に役立ちます:

  • 新しい機能を追加せずに、以前のリリースブランチにバグの修正をバックポートします。
  • マージできないブランチから作業を再利用します。
  • 試験的な変更を含めずに、以前のリリースに小さな機能のバックポートを行います。
  • 緊急本番環境修正(ホットフィックス)を開発ブランチに適用します。
  • フォークからアップストリームリポジトリに変更をコピーする。

GitLabユーザーインターフェースからチェリーピックする方法については、Cherry-pick changesを参照してください。

コミットをチェリーピックすると、Gitは次の処理を行います:

  • 現在のブランチに同じ変更内容で新しいコミットを作成します。
  • 元のコミットメッセージと作成者情報を保持します。 新しいコミットSHAを生成します。(元のコミットは変更されません)。
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
    accTitle: Example of cherry-picking a commit
    accDescr: Commit B is copied from the develop branch to the main branch while leaving the original branch unchanged.

 commit id: "A"
 branch develop
 commit id:"B"
 checkout main
 commit id:"C"
 checkout develop
 commit id:"D"
 checkout main
 commit id:"E"
 cherry-pick id:"B"
 commit id:"G"
 checkout develop
 commit id:"H"

git cherry-pickは、同一の変更内容で異なるセキュアハッシュアルゴリズム(SHA)を持つ重複したコミットを作成する可能性があるため、慎重に使用してください。これにより、プロジェクトの履歴が複雑になる可能性があります。最初にこれらの代替手段を検討してください:

  • ブランチ内のほとんどの変更が必要で、ブランチの履歴がクリーンな場合は、ブランチ全体を現在のブランチにマージします。
  • 元のコミットに新しいブランチで不要な複雑な依存関係が含まれている場合は、古いコミットをチェリーピックする代わりに、新しいコミットを作成します。

別のブランチに1つのコミットを適用する

単一のコミットを現在の作業ブランチにチェリーピックするには、次のようにします:

  1. チェリーピックするコミットのSHAを特定します。これを見つけるには、コミットの履歴を確認するか、git logコマンドを使用します。次に例を示します:

    $ git log
    
    commit abc123f
    Merge: 88888999999 aaaaabbbbbb
    Author: user@example.com
    Date:   Tue Aug 31 21:19:41 2021 +0000
    
        Fixes a regression we found yesterday
  2. チェリーピック先のブランチをチェックアウトします:

    git checkout release
  3. git cherry-pickコマンドを使用して、フィーチャーブランチからabc123fコミットをreleaseブランチにコピーします。abc123fを、特定したコミットのSHAに置き換えます:

    git cherry-pick abc123f

Gitは、コミットabc123fからreleaseブランチに変更をコピーし、競合が発生した場合は通知を表示します。競合を解決し、チェリーピックプロセスを続行します。コミットabc123fの内容が必要な各ブランチに対して繰り返します。

別のブランチに複数のコミットを適用する

必要なコードが複数のコミットの過程で追加された場合は、それらの各コミットを目的のターゲットブランチにチェリーピックします:

  1. チェリーピックするコミットのSHAを特定します。これを見つけるには、コミットの履歴を確認するか、git logコマンドを使用します。たとえば、コードの変更が1つのコミットにあり、改善されたテストカバレッジが次のコミットにある場合:

    $ git log
    
    commit abc123f
    Merge: 88888999999 aaaaabbbbbb
    Author: user@example.com
    Date:   Tue Aug 31 21:19:41 2021 +0000
    
        Fixes a regression we found yesterday
    
    commit ghi456j
    Merge: 44444666666 cccccdddddd
    Author: user@example.com
    Date:   Tue Aug 31 21:19:41 2021 +0000
    
        Adds tests to ensure the problem does not happen again
  2. チェリーピック先のブランチ(release)をチェックアウトします:

    git checkout release
  3. コミットをreleaseブランチにコピーします。

    • 各コミットをreleaseブランチに個別にコピーするには、各コミットに対してgit cherry-pickコマンドを使用します。abc123fghi456jを、目的のコミットのSHAに置き換えます:

      git cherry-pick abc123f
      git cherry-pick ghi456j
      ...
    • SHAを使用して始点と終点をマークし、releaseブランチにコミットの範囲をチェリーピックするには、..表記を使用します。このコマンドは、abc123fghi456jの間のすべてのコミットに適用されます:

      git cherry-pick abc123f..ghi456j

ブランチ全体の内容をコピーする

ブランチのマージコミットをチェリーピックすると、チェリーピックはブランチから現在の作業ブランチにすべての変更をコピーします。マージコミットをチェリーピックするには、-mフラグが必要です。このフラグは、使用する親コミットをGitに指示します。マージコミットには、作成方法に応じて複数の親コミットを含めることができます。

単純なケースでは、-m 1は最初の親を使用します。これは、ブランチのマージコミットです。2番目の親を指定するには、多くの場合、フィーチャーブランチがマージされる前の最後のコミットですが、代わりに-m 2を使用します。これらのフラグは、Gitが現在のブランチに適用する変更を決定します。

ブランチfeature-1から現在の作業ブランチにマージコミットをチェリーピックするには、次のようにします:

  1. チェリーピックするコミットのSHAを特定します。これを見つけるには、コミットの履歴を確認するか、git logコマンドを使用します。次に例を示します:

    $ git log
    
    commit 987pqr6
    Merge: 88888999999 aaaaabbbbbb
    Author: user@example.com
    Date:   Tue Aug 31 21:19:41 2021 +0000
    
        Merges feature-1 into main
  2. チェリーピック先のブランチをチェックアウトします:

    git checkout feature-2
  3. git cherry-pickコマンドを-mオプションとともに使用して、メインラインとして使用する親コミットのインデックスを指定します。<merge-commit-hash>をマージコミットのSHAに置き換え、<parent_index>を親コミットのインデックスに置き換えます。インデックスは1から始まります。次に例を示します:

    # git cherry-pick -m <parent_index> <merge-commit-hash>
    git cherry-pick -m 1 987pqr6

このコマンドを実行すると、Gitは987pqr6マージコミットの内容をfeature-2ブランチにコピーします。マージコミット987pqr6の代わりに、feature-1ブランチからの最後のコミットを使用する場合は、代わりに-m 2を使用します。

トラブルシューティング

チェリーピック中に競合が発生した場合:

  1. 影響を受けるファイルで競合を手動で解決します。

  2. 解決されたファイルをステージングします:

    git add <resolved_file>
  3. チェリーピックプロセスを続行します:

    git cherry-pick --continue

チェリーピックプロセスを中断して前の状態に戻すには、次のコマンドを使用します:

git cherry-pick --abort

これにより、チェリーピックプロセス中に行われた変更がすべて元に戻ります。