複数のコミットを選択する方法


875

私は2つの支店を持っています。コミットa他が持っている一方で、1のヘッドであるbcdefの上にa。私が移動したいcdeおよびfコミットせずに最初の分岐にb。チェリーピックを使用するのは簡単です。最初のブランチを1つずつチェリーピックでチェックアウトcf、2番目のブランチを最初にリベースします。しかし、チェリー選ぶすべてにどのような方法がありますc- f1つのコマンドで?

以下は、シナリオの視覚的な説明です(JJDに感謝)。

ここに画像の説明を入力してください


3
あなたが言及するリベースは質問に本当に関連していませんか?(後でbベースにすることもできますがf、チェリーピッキングとは関係ありません。)
スーパーロール2017

回答:


1282

Git 1.7.2では、さまざまなコミットを選択できる機能が導入されました。リリースノートから:

git cherry-pickコミットの範囲を選択することを学びました(例:cherry-pick A..Bおよびcherry-pick --stdingit revertrebase [-i]ただし、これらはより良いシーケンス制御をサポートしていません。

コミットからコミットAまでのすべてのコミットをチェリーピックするにはBAはより古いB)、次のコマンドを実行します。

git cherry-pick A^..B

A自体を無視する場合は、次のコマンドを実行します。

git cherry-pick A..B

(クレジットはコメントでダミアン、JB Rainsbergerとsschaefに行きます)


249
"cherry-pick A..B"形式では、AはBよりも古いはずです。順序が間違っていると、コマンドは通知なしで失敗します。
ダミアン

294
また、これはAの桜選ぶことはありませんが、むしろB.含めて最大A後のすべてのものと
JB Rainsberger

455
Aジャストタイプを含めるgit cherry-pick A^..B
キリクク2013

17
あなたはgitの1.7.1またはそれ以前のバージョンを持っており、更新できない場合は、かなり迅速に実行することにより、それらを順番に桜選ぶことができgit cherry-pick f~3、その後git cherry-pick f~2などまでgit cherry-pick f、私はすぐに数と実行を変更することができますので、前のコマンドを取得するまでの矢印を押します(それは、ほとんどのコンソールで似ているはずです)。
David Mason

19
この構文はブランチ名でも機能することを知っておくとよいでしょう。git cherry-pick master..somebranchマスター以降のブランチのすべてのコミットを選択し(すでにマスターに基づいていると仮定)、それらを現在のブランチに適用します。
Tor Klingberg、2016

103

これを行う最も簡単な方法は、ontoオプションを使用することrebaseです。現在仕上げの分岐と仮定amybranchと呼ばれ、これは、移動したいというブランチですc- fに。

# checkout mybranch
git checkout mybranch

# reset it to f (currently includes a)
git reset --hard f

# rebase every commit after b and transplant it onto a
git rebase --onto a b

1
ありがとうございました!git checkout secondbranch && git rebase mybranch完全な回答を追加してもらえますか
ティグ

1
この回答は、このシナリオでどのコミットがどれであるかを理解するのに大いに役立ちました。またrebase、のインタラクティブモードも使用できます。ありがとう、@ Charles!
オリバー

1
このアプローチの--interactive優れている点は、シーケンスから一部のコミットを削除したり、「チェリーピック」の前にそれらを並べ替えたりできることです。+1
マイケルメリケル2014年

これは巧妙なコマンドで、頭を回すには少しトリッキーですが、驚くほどうまくいきます。
Valerio

(この例では)引数の1つとしてリベースしたくないというコミットを与える必要がありますが、bこれは私にとってはうまくいきました。
asontu

85

または、要求されたワンライナー:

git rebase --onto a b f

5
簡潔にするためだけであれば、これが最良の答えです。
Nate Chandler

9
賛成ですが、fが(ブランチではなく)コミットの場合、分離したHEAD状態のままになります
Mr_and_Mrs_D

68

あなたはのシリアルを組み合わせて使用することができますgit rebaseし、git branch別のブランチにコミットのグループを適用します。wolfcによってすでに投稿されているように、最初のコマンドは実際にコミットをコピーします。ただし、グループの一番上のコミットにブランチ名を追加するまで、変更は表示されません。

画像を新しいタブで開いてください...

ワークフロー

コマンドをテキスト形式で要約するには:

  1. 次のコマンドを使用して、独立したプロセスとしてgitkを開きますgitk --all &
  2. を実行しますgit rebase --onto a b f
  3. プレスF5gitk。何も変わりません。ただし、HEADマークはありません。
  4. 走る git branch selection
  5. プレスF5gitk。コミットされた新しいブランチが表示されます。

これは物事を明確にするはずです:

  • コミットaは、グループの新しいルート宛先です。
  • コミットbは、グループの最初のコミットの前のコミットです(排他的)。
  • コミットfはグループの最後のコミットです(包括的)。

その後、あなたは使用することができますgit checkout feature && git reset --hard bコミットを削除するcまでffeature枝。

この回答に加えて、一般的な使用に役立つ別のシナリオのコマンドについて説明するブログ投稿を作成しました。


2
mybranch(a..fコミット)が不要になった場合、これは次のように簡略化できます。git rebase --onto a b mybranchそしてbtw-これらの気の利いたgit画像を実行するプログラムはどれですか。
Mr_and_Mrs_D 2014

2
@Mr_and_Mrs_Dコメントありがとうございます。絵を描くのにcacoo.comを使ったと思います。
JJD 2014

48

JB Rainsbergerとsschaefのコメントを適用して質問に具体的に回答するには...この例でチェリーピックの範囲を使用するには:

git checkout a
git cherry-pick b..f

または

git checkout a
git cherry-pick c^..f

3
私は使用していてgit 2.7.0.windows.1、コミットの範囲をチェリーピックしようとするとすべてが大丈夫ですが、gitはgit cherry-pick --continue | --abort | --quitコミット/チェリーピックを再度試みる前に行う必要があることをどこにも伝えません。したがって、コミットの範囲を正確に選択git cherry-pick --continueする場合は、所定の範囲からのコミットで準備が整うたびに(競合を解決するなど)実行する必要があります。
kuskmen 2016年

まったく同じでしたが、致命的でした。「a..b」が見つかりません
Amit

私はどこが間違っているのかわかりませんが、私の側で「git cherry-pick c ^ .. f」を実行すると、コミットfが含まれますが、コミットcは含まれません。しかし、どこでも読んだように、cとfを包括的に定義することになっています。それとも私は間違っていますか?
Samuel

@サミュエルはい、それは正しいです。^後にcが実際にこの場合はBである「Cの前にコミット」を意味します。これがc^..fと同じ意味b..fです。試してみるgit log c^..fと、コミットcからfまでが表示されます。実際と同じですgit log b..f
Andy

41

マージする選択リビジョンがある場合、たとえばA、B、C、D、E、F、G、H、I、JコミットからA、C、F、Jと言う場合は、次のコマンドを使用します。

gitチェリーピックACFJ


1
素晴らしくシンプル
スピンアップ

21
git rev-list --reverse b..f | xargs -n 1 git cherry-pick

2
競合がない場合は完璧に機能します。それ以外の場合は、停止した場所を特定して残りのパッチを再適用する必要がないため、「リベース」がより簡単になる場合があります。
Ruslan Kabalin、2011年

6
これが何をしているのかを説明するコメントを追加してください
Mr_and_Mrs_D

7
誰も説明しなかったので... git rev-listはブランチbからf(リバース)までのすべてのリビジョンを出力します。そのため、各行(コミットハッシュ)が順番に渡されると、現在のgit HEADにそれぞれを選択します。iegit cherry-pick {hash of c}; git cherry-pick {hash of d}; ...
coderatchet

8

ブランチの先端までコミットIDからチェリーピックするには、以下を使用できます。

git cherry-pick commit_id^..branch_name


これは既に回答の一部ですstackoverflow.com/a/31640427/96823
tig

1
この答えは実際には異なり、私に役立ちました。最終的なコミットSHAではなく、ブランチ名を指定します。
Subtletree

7

言及する価値のある別のバリ​​アントはn、ブランチからの最後のコミット~が必要な場合、構文が役立つことがあります:

git cherry-pick some-branch~4..some-branch

この場合、上記のコマンドは呼び出されたブランチから最後の4つのコミットを選択しsome-branchます(ブランチ名の代わりにコミットハッシュを使用することもできます)


1
非常に役立つ回答、ありがとうございます!:)
Jacek Dziurdzikowski

3

実際、最も簡単な方法は次のとおりです。

  1. 2つのブランチ間のマージベースを記録します。 MERGE_BASE=$(git merge-base branch-a branch-b)
  2. 古いブランチを新しいブランチに早送りまたはリベースする
  3. ステップ1のマージベースから始めて、結果のブランチをそれ自体にリベースし、不要なコミットを手動で削除します。

    git rebase ${SAVED_MERGE_BASE} -i
    

    または、新しいコミットが少ししかない場合は、ステップ1をスキップして、単に

    git rebase HEAD^^^^^^^ -i
    

    最初のステップで^は、マージベースを通過するのに十分な量を使用します。

インタラクティブなリベースに次のようなものが表示されます。

pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f

次に、行b(およびその他の必要なもの)を削除します。



0

次のスクリプトは、チェリーピックのソースとターゲットのブランチとコミット数をスクリプトに指示するだけで、複数のコミットを続けてチェリーピックできるようにするスクリプトです。

https://gist.github.com/nickboldt/99ac1dc4eb4c9ff003a1effef2eb2d81

ブランチからマスターにチェリーピックするには(現在のブランチをソースとして使用):

./gcpl.sh -m

6.19.xブランチからマスターへの最新の5つのコミットを選択するには:

./gcpl.sh -c 5 -s 6.19.x -t master

Gitで直接実行できるのに、なぜこのスクリプトが必要になるのでしょうか?...
code_dredd

入力の手間が省け、私のスクリプトが自動的にコミットを選択するので、SHAでコミットを個別に選択する必要はありません。とにかく、YMMV。
Nickboldt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.