2017-03-03 8 views
7

私は2つのブランチを持っています:ABです。git cherry-pickは、コミットのdiffを選ぶだけではありません。

  • Aのコミット履歴:a <- b <- c;
  • Bのコミット履歴:a <- h <- i;

ここに1つのファイルしかないとします。

  1. コミットbで、「foo」のようなテキストを追加します。
  2. コミットcで、「バー」のようなテキストを追加します。
  3. 次に、git cherry-pick cBブランチにあります。私はcherry-pickcの変更をBに拾うだけだと思った。ただし、ブランチBにはfoobarの両方が追加されます。明らかに私が望むものではありません。したがって

cherry-pickは祖先がaコミット以来でcをコミット触れたこれらのファイルのすべての変更を選択します。そうですか? bからcまでの差分を選択してiに適用する場合はどうすればよいですか?

更新正確な手順

  1. 初期Gitのレポ。
  2. ファイルtest.txtを追加し、最初のコミットinit commitを発行します。 test.txtは今です:

    first line 
    second line 
    
  3. は新しいブランチdevを作成しますが、ブランチmasterにとどまります。

  4. ファイルにadded in commit bを追加し、コミットbを発行します。 test.txtは今です:

    first line 
    added in commit b 
    second line 
    
  5. は、ファイルにadded in commit cを追加し、コミットcを発行します。 test.txtは今:

    first line 
    added in commit b 
    added in commit c 
    second line 
    
  6. devブランチをチェックアウトしてコミットhを発行します。 test.txtは今です:チェリーピックへ

    first line 
    second line 
    
    adding by commit h 
    
  7. git cherry-pick <commit c SHA1 ID>はコミットhcをコミットします。

  8. 競合メッセージ:

    index 6a8dc57,594c6ec..0000000 
    @@@ -1,4 -1,4 +1,9 @@@ 
        first line 
    ++<<<<<<< HEAD 
    ++======= 
    + added in commit b 
    + added in commit c 
    ++>>>>>>> 06ce9b1... commit c adding another line 
        second line 
    + 
    +adding by commit h 
    
  9. 参照してください?cherry-pickもコミットで変更されましたb

ありがとう!

+0

これは、あなたのhttpを助けることがあります。 //stackoverflow.com/questions/9339429/what-does-cherry-picking-a-commit-with-git-mean –

+0

@ArunGありがとう!私は「チェリーピック」とは何かを知っています。しかし、私はちょうどそのコミットの差分を取得し、diffをターゲットブランチに適用することと同じではないと混乱しています。そのコミットには内容** NOT **も含まれています。 – tamlok

+0

@tamlok、 'git show a'(明らかに関連するコミットSHAで' a 'を置き換える)を実行して、コミットが実際に導入される変更を調べて、なぜデルタをコミット 'b'から得るのかを確認します。 '-n'フラグをつけて' cherry-pick'を実行するといつでも停止して、望ましくない変更を手動で取り除くことができます。 – miqid

答えて

4

git cherry-pickコミットを1つだけ試行します。しかし、いくつかの文脈を必要とするパッチを適用することでこれを行います。コミットCで行われた変更は、コミットbによって行われた変更に非常に近いので、変更を適用する必要がある正しい場所を見つけることはできません。あなたが競合しているときに、あなたはまた、少なくとも、あなたのコミットB.

の一部が、ここでは、競合することなくうまくいく方法ですされ、競合状況の一部を取得:

$ git init 
$ cat > f 
line1 
line2 
line3 
$ git add f 
$ git commit -a -m "initial" 
# Edited to add a line in the beginning of f 
$ cat f 
Commit b 
line1 
line2 
line3 
$ git commit f -m "B" 
# Edited to add a line in the end of f 
$ cat f 
Commit b 
line1 
line2 
line3 
Commit c 
$ git commit f -m "C" 
$ git checkout HEAD^^ 
$ git cherry-pick master 
$ cat f 
line1 
line2 
line3 
Commit c 
+0

'git cherry-pick master 'は' b'と 'c'の両方ではなく' c'を選ぶだけですか?これは、 'git cherry-pick'でブランチ名を使用するとき、最後のコミットだけを選択するでしょうか?ありがとう! – tamlok

+0

私はちょうど 'git cherry-pick master'を試しました。結果は同じですが、競合の内容には依然としてコミット 'b'の変更が含まれています。 :( – tamlok

+0

ありがとう! – tamlok

0

私はbからcへの差分を選んでiに適用したいのですが?

2つのコミット(c..d)間のファイルのdiffを検索/書き込みできます。その後、現在の支店でそれを適用します。

$ git checkout <B-branch> 

# write the diff in a file named 'change.patch' (root directory) 
$ git diff <b-commit> <c-commit> <file-name> >> ~/changes.patch 

$ git apply ~/changes.patch  # apply the changes 
$ git add . 

# merge the changes to i (previous commit) 
$ git commit --amend -m 'Apply the diff of b and c' 

$ git push -f origin HEAD  # force(-f) push since history is changed 
+0

私はこの「元の」方法を知っています。しかし、 'git cherry-pick'の記述によれば、他の指定されていないコミットから余分な変更をもらうのはなぜですか?ありがとう! – tamlok

+0

私の場合、パッチは完全には適用されないので、3ウェイマージには ' - 3way'オプションを使用する必要があります。 'git cherry-pick'を使った場合と全く同じ結果が得られますが、そこではエラーがミュートされていますが、頭のない3つの方法に戻ってしまうようです。私はまだ3者の合併がその結果と結びつくのはなぜか分かりませんが、私の2つの支部はかなり分かれており、それは関連性があります。 – angularsen

関連する問題