2

私はGitが初めてです。

新しいブランチを作成しましたnew_branch。すべての変更とコミットを別のブランチで行いましたold_branchold_branchここで、ブランチからnew_branchbyへのコミットをいくつか選択したいと思いgit cherry-pickます。そのためには、まずどのコミットがそのブランチにあるかを知り、次にそれらを選択して とマージする必要がありnew_branchます。

これどうやってするの?

4

3 に答える 3

0

@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_branchold_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 ... の名前を削除します。reviserebase -ireviserevise-1reviserevise-1rebase -i


脚注: 上記で「放棄」とマークされたコミットはまだそこにあり、reflog を介してガベージ コレクションに対して保持されていますが、最終的には reflog エントリが期限切れになり、git gc. それまでは、それらはほとんど見えません: たとえば、表示されませんgit log --allgitk --allこれらのコマンドは で実行できますが--reflog、ブランチ ラベルがない場合でも、見つけるのは少し難しいです。私はしばらくそれらにぶら下がっているのが好きなので、上記の複数のブランチ名のワークフローです。

于 2013-07-30T12:30:32.930 に答える