2017-03-03 7 views
7

나는 두 개의 가지 : AB을 가지고 있습니다.git cherry-pick은 커밋의 diff를 선택하지 않습니다.

  • A의 커밋 내역 : a <- b <- c;
  • B 님의 커밋 내역 : a <- h <- i;

여기에는 파일이 하나만 있다고 가정합니다.

  1. 커밋 b에서 "foo"와 같은 텍스트를 추가합니다.
  2. 커밋 c에서 "bar"와 같은 텍스트를 추가합니다.
  3. 그러면 git cherry-pick cB 분기입니다. 나는 cherry-pick이 지점에 c의 변경 사항만을 고를 것이라고 생각했습니다. 그러나 지점 Bfoobar이 모두 추가됩니다. 나는 분명히 내가 원하는 바가 아니다. 따라서

, cherry-pick는 조상 a 커밋 이후에 c를 저지 만진 해당 파일의 모든 변경 사항을 선택합니다. 그게 맞습니까? b에서 c까지 diff를 선택하여 i에 적용하려면 어떻게해야하나요?

업데이트 정확한 단계

  1. 초기화 자식의 REPO;
  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>h 커밋에 c을 커밋합니다.

  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 : 당신이 충돌이있을 때, 당신은 적어도 당신의 B.

여기가 충돌없이 작동 할 방법을 저지하는 것은의 일부입니다 충돌하는 상황의 일부를 얻을 //stackoverflow.com/questions/9339429/what-does-cherry-picking-a-commit-with-git-mean –

+0

@ArunG 감사합니다! 나는 체리 피크가 무엇을 의미하는지 안다. 그러나 나는 그 커밋의 diff를 얻고 diff를 타겟 브랜치에 적용하는 것과 같지 않다는 것을 혼란스러워한다. 또한 커밋에 ** ** ** 내용이 포함되어 있습니다. – tamlok

+0

@tamlok, 커밋'b'에서 델타를 얻는 이유를 확인하기 위해 커밋이 실제로 적용될 변경 사항을 조사하기 위해'git show a' ('a'를 관련 커밋 SHA로 바꾸십시오)를 실행하십시오. '-n' 플래그로 항상'cherry-pick'을 실행하여 원하지 않는 변경 사항을 중지하고 수동으로 제거 할 수 있습니다. – miqid

답변

4

git cherry-pick은 하나의 커밋을 시도합니다. 그러나 일부 상황을 요구하는 패치를 적용하여이를 수행합니다. 커밋 C에서 수행 된 변경은 커밋 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

diff를 b에서 c까지 선택하여 i에 적용하려면 어떻게해야합니까?

당신은 찾을 수

/두 커밋 (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 가지 방법으로 병합이 그 결과와 끝나는 것을 보지 못한다. 그러나 내 두 가지가 서로 엇갈려 관련성이있다. – angularsen