私はGitが初めてです。
新しいブランチを作成しましたnew_branch
。すべての変更とコミットを別のブランチで行いましたold_branch
。old_branch
ここで、ブランチからnew_branch
byへのコミットをいくつか選択したいと思いgit cherry-pick
ます。そのためには、まずどのコミットがそのブランチにあるかを知り、次にそれらを選択して とマージする必要がありnew_branch
ます。
これどうやってするの?
私はGitが初めてです。
新しいブランチを作成しましたnew_branch
。すべての変更とコミットを別のブランチで行いましたold_branch
。old_branch
ここで、ブランチからnew_branch
byへのコミットをいくつか選択したいと思いgit cherry-pick
ます。そのためには、まずどのコミットがそのブランチにあるかを知り、次にそれらを選択して とマージする必要がありnew_branch
ます。
これどうやってするの?
@naomi が提供する方法は問題なく機能しますが、もっと簡単な方法があります。old_branch
次のように、他のブランチのコミットから始まるブランチがあります。
A --- B --- C --- D <-- devel (let's say it's branch devel, anyway)
\
E - F - G - H <-- old_branch
いくつかのコミット (おそらく B または C または D) からブランチを作成しnew_branch
、コミット E、F、G、および/または H のいくつかを選択したいと考えています (おそらく、コミットのはるかに長い文字列ですが、これは物事を説明する必要があります)。
通常、未公開の一連の作業 (おそらくold_branch
そのような一連の作業) を取得して、最新のもの (commit D) の上に「移動」したい場合は、次のようにします。
$ git checkout old_branch # get onto old_branch
$ git rebase devel # and rebase it onto commit D in "devel"
それは、E から H までのコミットの「コピー」を作成し、「D」の後にそれぞれを追加することです。次に、ラベル (以前はコミット H という名前でした) をはがし、それold_branch
を H のコピーに貼り付けて、次のようにします。
A --- B --- C --- D <-- devel
\ \
\ E' - F' - G' - H' <-- old_branch
\
E - F - G - H [abandoned, see footnote]
あなたが望むのは、いくつかのコミットを選択することです.C(new_branch
上記で作成した場所はどこでも)としましょう。同じことをしますが、「ラベルをはがす」ことはしませんold_branch
。さらに、E、F、G、および H のどれがそこに行くかを選択します。すべて完了したら、ラベルをnew_branch
追加します。それは実際にはとても簡単です。new_branch
コミット C でブランチを作成する代わりに、の先頭であるコミット H でブランチを作成しold_branch
ます。
$ git checkout old_branch; git checkout -b new_branch
Nownew_branch
とold_branch
は内容的には同じですが、名前が異なります。
これで、移動したいポイントに簡単にrebase -i
(インタラクティブに選択できます)移動できます。new_branch
ここでcommit を想定してきましたがC
、これは という名前のブランチ チップから 1 ステップ後退したものであると想定しているdevel
ので、それで実行します。
$ git rebase -i --onto devel~1 devel new_branch
許可する方法を選択して選択した後rebase -i
(そして、いくつかのコミットを削除して競合を解決し、解決git rebase --continue
後に続行する)、取得するコミットと削除するコミットに応じて、このような結果になります。F を削除すると仮定しますが、残りは保持します。
A --- B --- C --- D <-- devel
\ \
\ E' - G' - H' <-- new_branch
\
E - F - G - H <-- old_branch
git branch
. _ new_branch
_ old_branch
_ rebase -i
また、どんなブランチの先端にも行きたいと思うでしょう。つまり、リベースするのではなく、--onto devel~1
(の先端) にリベースしたいだけですdevel
。この場合--onto
、結局のところ、その部分は必要ありません。
$ git branch new_branch old_branch
$ git rebase -i devel new_branch
ここでの結果は、コミット E' が C ではなく D から外れていることを除いて、以前とほとんど同じです。
A --- B --- C --- D <-- devel
\ \
\ E' - G' - H' <-- new_branch
\
E - F - G - H <-- old_branch
これは基本的に、未公開の変更をやり直すときに私が行うことです。私が(たとえば)ブランチrevise
にいる場合は、名前を に変更し、同じ場所にrevise-0
新しいブランチを作成してから、少しクリーンアップします。その 1 回のパスの後、もう一度修正することを決定する可能性があるため、 に名前を変更して、同じ場所に新しいものを作成し、もう一度、などです。それらが必要ないと判断するまで。次に、すべての -0 -1 -2 ... の名前を削除します。revise
rebase -i
revise
revise-1
revise
revise-1
rebase -i
脚注: 上記で「放棄」とマークされたコミットはまだそこにあり、reflog を介してガベージ コレクションに対して保持されていますが、最終的には reflog エントリが期限切れになり、git gc
. それまでは、それらはほとんど見えません: たとえば、表示されませんgit log --all
。gitk --all
これらのコマンドは で実行できますが--reflog
、ブランチ ラベルがない場合でも、見つけるのは少し難しいです。私はしばらくそれらにぶら下がっているのが好きなので、上記の複数のブランチ名のワークフローです。