Gitでコミットをチェリーピッキングするとはどういう意味ですか?


2340

最近、私はcherry-pickコミットを求められました。

では、gitでコミットをチェリーピッキングするとはどういう意味ですか?どうやってやるの?


13
マージする代わりに、チェリーピッキングを使用すると、ブランチからターゲットブランチ(例:マスター)に再コミットする方が簡単です。
Levent Divilioglu

回答:


2859

Gitでのチェリーピッキングとは、1つのブランチからコミットを選択し、それを別のブランチに適用することを意味します。

これは、次のような他の方法とは対照的であるmergerebase、通常は別の枝に多くのコミットを適用します。

  1. コミットを適用するブランチにいることを確認してください。

    git checkout master
    
  2. 以下を実行します。

    git cherry-pick <commit-hash>
    

注意:

  1. 公共のブランチからチェリーピックする場合は、使用を検討する必要があります

    git cherry-pick -x <commit-hash>
    

    これにより、標準化されたコミットメッセージが生成されます。このようにして、あなた(そしてあなたの同僚)はまだコミットの起源を追跡することができ、将来のマージの競合を避けることができます。

  2. コミットに添付されたメモがある場合、それらはチェリーピックに従いません。同様にそれらをもたらすには、使用する必要があります:

    git notes copy <from> <to>
    

追加リンク:


247
パブリックブランチからチェリーピックする場合は、の使用を検討する必要がありますgit cherry-pick -x <commit-hash>。これにより、標準化されたコミットメッセージが生成されます。このようにして、あなた(そしてあなたの同僚)はコミットの起源を追跡し続けることができ、将来のマージの競合を避けることができます。
MBober 2014年

2
桜狩りは本当に必要ですか?混合リセットまたはソフトリセットは同様の機能を果たしませんか?
ナビゲーション

10
コミットに添付されたメモがある場合、それらはチェリーピックに従っていないことに注意してください。あなたもgit notes copy <from> <to>それらをもたらすために使用する必要があります。
Zitrax

5
git pushはマスターに変更を加える最後のステップです
気分が良く、プログラミング

58
参考:コミットには、その瞬間の作業ツリーのすべてのファイル(および前のコミットのコミットハッシュ)が意味的に含まれるため、コミット全体を別のコミットに適用するのではなく、コミットが前のコミットで行った変更"cherry-pick commit applies the changes introduced by the named commit on the current branch"ほとんどpplはコミットを変更(svn was iircのような)と考える傾向がありますが、そうではありません。各コミットは完全な作業ツリーを参照します。これはこの場合に違いはありませんが、Gitが動作する理由を理解するのに役立ちます。
Emile Vrijdags 2017

314

この引用は、 Gitを使用したバージョン管理 (本当に素晴らしい本です。gitに興味がある場合は購入することをお勧めします)

編集:この答えはまだ印象的であるので、それについて非常に素晴らしいアクションビデオチュートリアルを追加したいと思います。

Youtube:Gitチェリーピックの紹介

git cherry-pickコマンドの使用git cherry-pick commitコマンドは、現在のブランチの名前付きコミットによって導入された変更を適用します。これは、新しい明確なコミットを導入します。厳密に言うと、git cherry-pickを使用しても、リポジトリ内の既存の履歴は変更されません。代わりに、履歴に追加されます。差分を適用するプロセスを介して変更を導入する他のGit操作と同様に、特定のcommitからの変更を完全に適用するには、競合を解決する必要がある場合があります。コマンドgit cherry-pickは通常、リポジトリ内のあるブランチから別のブランチに特定のコミットを導入するために使用されます。一般的な用途は、メンテナンスブランチから開発ブランチにコミットを転送またはバックポートすることです。

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

前: 前

後: 後


12
チェリーピックのコミットがいくつかのブランチ(b1)で行われ、後でマスターに配信されたとき。また、ブランチb1(最初にコミットが選択されたもの)もマスターに配信されようとしている場合。紛争はどうですか?それは大丈夫ですか、それともどのように機能しますか?
parasrish 2016年

3
@parasrishはい、彼らはあなたの以前のマージですでに世話をされています。したがって、(b1)ブランチからa、b、c、dを変更しました。"c"だけを選んだチェリー。その後、(b1)からマスターにマージすると、「c」の変更は同じであるため、a、b、dのみがマージされ、「c」の変更が残ります。ただし、マージをロールバックすると、「c」を含む変更が元に戻ります。それらを個別にロールバックする必要があります。
Teoman Shipahi 2016年

12
それは強調されるべきです:与えられた例で、差(F-E)だけがZに適用されます。これは狭いケースです。Cherry-Pickは、複数のコミットの違い、たとえば、隣接していない2つのコミットの違いのすべてを適用するために使用できます。たとえば、上から(F-E)、(E-D)、(D-C)、および(C-B)です。これは、差(F-B)を適用することと同じです。
Thomas Bitonti

2
また、選択したコミット(例ではF)に複数の直前のコミットがある場合はどうなりますか?
Thomas Bitonti

2
つまり、@ j2emanueは、cherry-pickはラストコミットの変更のみを取得します。3つの異なる時間をコミットし、最後の1つを選択した場合、最初と2番目のコミットで変更は行われません。Mergeコマンドはすべての変更を受け取り、ターゲット(マスター)ブランチに適用します。
Teoman Shipahi

157

Gitでのチェリーピッキングは、あるブランチから別のブランチにコミットを適用するように設計されています。たとえば、間違いを犯し、間違ったブランチに変更をコミットしましたが、ブランチ全体をマージしたくありません。あなたはちょうどすることができます。コミットを元に戻し、別のブランチにチェリーピックします。

それを使用するには、他のブランチからのコミットハッシュgit cherry-pick hashがどこにあるかhashが必要です。

完全な手順については、http//technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.htmlを参照してください。


96

チェリーピックが必要な状況の短い例

次のシナリオを検討してください。2つのブランチがあります。

a)release1-このブランチはお客様に提供されますが、まだ修正されていないバグがいくつかあります。

b)マスター -クラシックマスターブランチ。ここでは、たとえばrelease2の機能を追加できます。

NOWrelease1で何かを修正します。もちろん、この修正はマスターでも必要です。そして、それはチェリーピッキングの典型的なユースケースです。したがって、このシナリオでのチェリーピックは、リリース1ブランチからコミットを取得して、マスターブランチに含めることを意味します。


3
他の方法が必要な場合もあります。あなたはマスターのバグを修正し、それをrelease1にチェリーピックする必要があります。また、ブランチではなくリポジトリである可能性もあります
canbax

1
なぜマージを使用しないのですか?
FreeLightman

私は:ブランチオフリリースを作成し、ブランチで修正し、リリースでブランチをマージし、マスターでリリースをマージします。
Jasper-M

57

cherry-pickはGitの機能です。あるブランチの特定のコミットをターゲットブランチにコミットしたい場合は、チェリーピックを使用します。
git cherry-pickの手順は次のとおりです。

  1. ターゲットブランチをチェックアウト(切り替え)します。
  2. git cherry-pick <commit id>
    

    ここで、コミットIDは別のブランチのアクティビティIDです。

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. ターゲットブランチにプッシュ

訪問https://git-scm.com/docs/git-cherry-pick


44

私は、どのようなステップバイステップのイラスト準備チェリーピックと-んをこれらの図のアニメーション(近端)。

  1. チェリーピックする前に
    (ブランチからコミットのチェリーピックを行います): Lfeatureここに画像の説明を入力してください

  1. コマンドを開始しますgit cherry-pick feature~2
    feature~22 番目のコミット
    feature、つまりコミットですL): ここに画像の説明を入力してください

  1. コマンド(git cherry-pick feature~2)を実行した後: ここに画像の説明を入力してください

同じアニメーション: ここに画像の説明を入力してください


注意:

コミットL'、ユーザーの観点(commit = snapshot)からのコミットの正確なコピーですL

技術的に(内部的に)、これは新しい別のコミットです(たとえばLK(その親として)L'へのポインタを含み、へのポインタを含むためE)。


それは、L 'がブランチマスターでN-> M-> Lになるということですか?または、マスターブランチにコミットLを排他的に
適用します

1
@PriyankThakkar、はい、もっぱらL、他には何もありません(写真/アニメーションからわかるように)。
MarianD

22

あなたはチェリーピックがリベースに似ているか、それともリベースのように管理されているかを考えることができます。これは、既存のコミットを取得し、現在のブランチのヘッドを開始点として再生成することを意味します。

A rebaseは、親Xがあったコミットを取得し、実際に親Yがあったかのようにコミットを再生成cherry-pickします。これがまさにa が行うことです。

チェリーピックは、コミットの選択方法に関する詳細です。pull(リベース)、gitのは、暗黙のうちにあなたのブランチに引っ張られているものの上に、あなたの地元のコミットを再生成しますが、とcherry-pick明示的にいくつかの(s)がコミットを選択し、暗黙のうちにあなたの現在のブランチの上に(それらを)再生成します。

そのため、方法は異なりますが、内部的には非常によく似た操作、つまりコミットの再生成です。


1
私はこれが物事の非常に役立つ見解であると思います。これcherry-pickは、ターゲットブランチが後でマージされてソースブランチに戻ったときの動作と同じになる理由を示しています。ありがとうございます。
Aluan Haddad 2017

3
機能の完了後、git mergeではなくチェリーピックを使用したいと思います。誰もが機能を完了すると、常にgit merge feature_branchを実行します。cherry-pickコマンドを使用しないのはなぜですか?あなたは何か考えを持っていますか?私がチェリーピックすることができるなら、なぜ
つぶしを

11

コピー(どこかから)や貼り付け(どこかに)のようなものですが、特定のコミットのためのものです。

たとえば、ホットフィックスを実行する場合は、このcherry-pick機能を使用できます。

あなたの操作を行いcherry-pick開発ブランチで、かつmergeそのリリースブランチにコミットします。同様に、cherry-pickリリースブランチからマスターへのブランチを行います。出来上がり


11

プロジェクトで開発者のチームと協力している場合、多数のgitブランチ間の変更の管理が複雑なタスクになる可能性があります。ブランチ全体を別のブランチにマージしたくない場合があり、1つまたは2つの特定のコミットのみを選択する必要があります。このプロセスは「チェリーピッキング」と呼ばれます。

チェリーピッキングに関する素晴らしい記事を見つけました。詳細については、https//www.previousnext.com.au/blog/intro-cherry-picking-gitをご覧ください。


7

コミットIDなしでマージしたい場合は、このコマンドを使用できます

git cherry-pick master~2 master~0

上記のコマンドは、マスターの最後の3つのコミットを1から3にマージします

単一のコミットでこれを実行したい場合は、最後のオプションを削除してください

git cherry-pick master~2

このようにして、マスターの最後から3番目のコミットをマージします。


これは紛らわしいです。マスター以外のブランチにいると思いますよね?また、2つのコミットについて言及した場合は、チェリーピックする範囲を定義するために<from>および<to>コミットを参照しています。正しい?シナリオが説明されていれば非常に役立ちます。加えて良い。ありがとう。
Saurabh Patil

6

現在のブランチに特定のコミットを適用します。

これの意味は :

  • このコミットによって追加されたすべてのファイルが追加されます
  • このコミットによって削除されたすべてのファイルが削除されます
  • このコミットによって変更されたすべてのファイルがマージされます。これはこのコミットからの変更だけでなく、コミットからのファイル全体を意味します

例:コミットAを検討する

added newFileA
modified main:
+ import './newFileA'

コミットB

added newFileB
modified main:
+ import './newFileB'

別のブランチでcommit Bチェリーピックすると、次のようになります。

/newFileB
/main :
   import './newFileA'
   import './newFileB'

以来、Bがコミット含まnewFileBメイン、ないnewFileA、バグが生じが、そう注意して使用します。


0

公式ドキュメントからの抜粋:

1つ以上の既存のコミットを前提として、それぞれが導入する変更を適用し、それぞれの新しいコミットを記録します。これには、作業ツリーをクリーンにする必要があります(HEADコミットからの変更はありません)。

変更を適用する方法が明らかでない場合、次のことが起こります。

  1. 現在のブランチとHEADポインターは、正常に行われた最後のコミットに留まります。

  2. CHERRY_PICK_HEAD参照は、適用が難しい変更を導入したコミットを指すように設定されています。

  3. 変更が完全に適用されたパスは、インデックスファイルと作業ツリーの両方で更新されます。

  4. パスが競合する場合、git-mergeの「TRUE MERGE」セクションで説明されているように、インデックスファイルは最大3つのバージョンを記録します。作業ツリーファイルには、通常の競合マーカー<<<<<<<および>>>>>>>で囲まれた競合の説明が含まれます。

他の変更は行われません。

続きを読む...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.