17

2つのブランチが分岐しており、一方のブランチ(すべてではない)からの特定のコミットをもう一方のブランチに導入する必要があることを考えると、gitcherrypickはまさにそれを実現します。

しばらくすると、2つのブランチを完全にマージする必要があります。gitは、それが再導入されないように、過去にチェリーピックされたコミットがすでにあることをどのように知るのでしょうか?

4

2 に答える 2

30

tonioの回答で言及されている「重複コミットの回避」の記事は次のように述べています。

マスターブランチとブランチbがあると想像してください。

  o---X   <-- master
   \
    b1---b2---b3---b4   <-- b

ここで、マスターにコミットb1とb3が緊急に必要ですが、bの残りのコミットは必要ありません。したがって、マスターブランチをチェックアウトし、cherry-pickがb1とb3をコミットします。

$ git checkout master
$ git cherry-pick “b1’s SHA”
$ git cherry-pick “b3’s SHA”

結果は次のようになります。

  o---X---b1'---b3'   <-- master
   \
    b1---b2---b3---b4   <-- b

マスターに対して別のコミットを実行すると、次のようになります。

  o---X---b1'---b3'---Y   <-- master
   \
    b1---b2---b3---b4   <-- b

ブランチbをマスターにマージする場合:

$ git merge b

次のようになります。

  o---X---b1'---b3'---Y--- M  <-- master
   \                     /
     b1----b2----b3----b4   <-- b

つまり、b1とb3によって導入された変更は、履歴に2回表示されます。これを回避するには、マージの代わりにリベースできます。

$ git rebase master b

どちらが得られますか:

  o---X---b1'---b3'---Y   <-- master
                       \
                        b2---b4   <-- b

ついに:

$ git checkout master
$ git merge b

私たちに与える:

  o---X---b1'---b3'---Y---b2---b4   <-- master, b

このスレッドの後)


OPはコメントに追加します:

しかし、それでも私はリベースがどのように機能するかを完全には理解していないようです。つまり、リベースした後でも、チェリーピックされたコミットはまだ表示されるべきではありませんか?

いいえ。mangit commitページには次のように明示的に記載されています。

アップストリームブランチに、行った変更がすでに含まれている場合(たとえば、アップストリームに適用されたパッチをメールで送信したため)、そのコミットはスキップされます。
たとえば、次の履歴でgit rebase masterを実行します(A'とAは同じ変更セットを導入しますが、コミッター情報は異なります)。

      A---B---C topic
     /
D---E---A'---F master

結果は次のようになります。

               B'---C' topic
              /
D---E---A'---F master

コミットがマスターにすでに存在するかどうかを検出できますgit cherry mastertopicブランチにいる場合)。

于 2010-04-13T10:54:38.247 に答える
16

あなたは読みたいかもしれません

Git Cherry-pickとMergeワークフローを比較して、mergeとcherry-pickを適切に比較します。特に、cherry-pickは親IDを保存しないため、過去にcherrypickされたコミットがすでに存在することを認識しません。それを再導入しません。

http://davitenio.wordpress.com/2008/09/27/git-merge-after-git-cherry-pick-avoiding-duplicate-commits/この場合、を使用してコミットの重複を回避する方法についてrebase

于 2010-04-13T08:33:28.213 に答える