Git으로 커밋을 고르는 것은 무엇을 의미합니까?


2336

최근에 나는 cherry-pick커밋을 요청 받았다 .

git에서 커밋을 고르는 것은 무엇을 의미합니까? 어떻게합니까?


13
병합 대신 지점에서 대상 지점으로 체리 피킹을 다시 커밋하는 것이 더 쉽습니다 (예 : 마스터).
Levent Divilioglu

답변:


2855

Git에서의 체리 피킹은 한 지점에서 커밋을 선택하여 다른 지점에 적용하는 것을 의미합니다.

이 같은 다른 방법과는 대조적이다 merge그리고 rebase일반적으로 다른 지점에 많은 커밋을 적용합니다.

  1. 커밋을 적용하려는 지점에 있는지 확인하십시오.

    git checkout master
    
  2. 다음을 실행하십시오.

    git cherry-pick <commit-hash>
    

NB :

  1. 공공 지점에서 체리 픽을 선택하면

    git cherry-pick -x <commit-hash>
    

    표준화 된 커밋 메시지가 생성됩니다. 이런 식으로, 귀하 (및 동료)는 여전히 커밋의 출처를 추적 할 수 있으며 향후 병합 충돌을 피할 수 있습니다.

  2. 커밋에 첨부 된 메모가 있으면 체리 픽을 따르지 않습니다. 그것들을 가져 오려면 다음을 사용해야합니다.

    git notes copy <from> <to>
    

추가 링크 :


246
공개 지점에서 체리 픽을 선택하는 경우을 사용하는 것이 git cherry-pick -x <commit-hash>좋습니다. 표준화 된 커밋 메시지가 생성됩니다. 이런 식으로, 귀하 (및 동료)는 여전히 커밋의 출처를 추적 할 수 있으며 향후 병합 충돌을 피할 수 있습니다.
MBober

2
체리 따기가 정말로 필요한가요? 혼합 재설정 또는 소프트 재설정이 유사한 작업을 수행하지 않습니까?
Nav

10
커밋에 첨부 된 노트가 있으면 체리 픽을 따르지 않습니다. git notes copy <from> <to>그것들을 가져 오려면 사용해야 합니다.
Zitrax

5
git push는 마스터에 변화를 가져 오는 마지막 단계입니다
기분이 좋으며 프로그래밍하기

58
참고 : 커밋에는 의미 적으로 해당 순간의 작업 트리의 모든 파일 (및 이전 커밋의 커밋 해시)이 포함되므로 다른 커밋에 전체 커밋을 적용하지 않지만 이전 커밋에서 커밋이 수행 한 변경 사항 "cherry-pick commit applies the changes introduced by the named commit on the current branch"대부분 ppl은 커밋을 변경으로 생각하는 경향이 있지만 (svn은 iirc와 같음) 각 커밋이 완전한 작업 트리를 참조하는 것은 아닙니다. 이것은이 경우에는 차이가 없지만 git이 왜 그렇게 작동하는지 이해하는 데 도움이 될 수 있습니다.
Emile Vrijdags

314

이 인용문은 다음과 같습니다. Git을 사용한 버전 관리 (정말 훌륭한 책, git에 관심이 있다면 구입하는 것이 좋습니다)

편집 :이 답변은 여전히 ​​인상적이기 때문에 액션 비디오 자습서에 대해 매우 훌륭하게 추가하고 싶습니다.

유튜브 : 깃 체리 픽 소개

git cherry-pick 사용 git cherry-pick commit 명령은 현재 브랜치에서 명명 된 commit에 의해 도입 된 변경 사항을 적용합니다. 새롭고 뚜렷한 커밋을 소개합니다. 엄밀히 말하면, git cherry-pick을 사용한다고해서 리포지토리 내의 기존 기록이 변경되지는 않습니다. 대신 기록에 추가됩니다. diff를 적용하는 프로세스를 통해 변경 사항을 도입하는 다른 Git 작업과 마찬가지로 충돌을 해결하여 주어진 커밋의 변경 사항을 완전히 적용해야 할 수도 있습니다 . git cherry-pick 명령은 일반적으로 저장소 내의 한 분기에서 다른 분기로 특정 커밋을 도입하는 데 사용됩니다. 일반적으로 유지 보수 브랜치에서 개발 브랜치로 포워드 또는 백 포트 커밋을 사용합니다.

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

전에: 전에

후: 후


12
체리 브랜치 커밋이 일부 브랜치 (b1)에서 수행되어 나중에 마스터에게 전달되는 경우. 그리고 b1 (커밋이 원래 선택된 지점)도 마스터로 전달하려고 시도합니다. 갈등은 어떻습니까? 관리가 잘 되었습니까 아니면 어떻게 작동합니까?
parasrish 2016 년

3
@parasrish 예, 그들은 이미 이전 합병을 처리했습니다. 따라서 (b1) 지점에서 a, b, c, d를 변경했습니다. 체리는 "c"만 골랐습니다. 그런 다음 나중에 (b1)에서 마스터로 병합하면 "c"변경 사항이 동일하므로 a, b, d 만 병합하고 "c"변경 사항 만 유지합니다. 그러나 병합을 롤백하면 "c"가 포함 된 변경 사항이 다시 적용됩니다. 별도로 롤백해야합니다.
Teoman shipahi

12
주어진 예에서, 차이 (F-E) Z에 적용됩니다. 이것은 좁은 경우입니다. Cherry-pick은 여러 커밋의 차이, 예를 들어 두 개의 인접하지 않은 커밋 사이의 모든 차이점을 적용하는 데 사용될 수 있습니다. 예를 들어, 위에서 다음과 같이 (F-E), (E-D), (D-C) 및 (C-B)입니다. 이는 차이 (F-B)를 적용하는 것과 같습니다.
Thomas Bitonti

2
또한 선택한 커밋 (예 : F)에 둘 이상의 직계 선행 작업이 있으면 어떻게됩니까?
Thomas Bitonti

2
다시 말해 @ j2emanue, cherry-pick은 마지막 커밋의 변경 사항 만 적용합니다. 세 번 다른 커밋을하고 마지막으로 체리를 선택하면 첫 번째와 두 번째 커밋에서 변경 사항이 적용되지 않습니다. 병합 명령은 모든 변경 사항을 적용하여 대상 (마스터) 지점에 적용됩니다.
Teoman shipahi

157

Git에서의 체리 피킹은 한 지점에서 다른 지점으로 커밋을 적용하도록 설계되었습니다. 예를 들어 할 수 있습니다. 실수를하고 잘못된 지점으로 변경했지만 전체 지점을 병합하고 싶지는 않습니다. 당신은 예를 들어 할 수 있습니다. 커밋을 되돌리고 다른 지점에서 체리를 선택하십시오.

그것을 사용하기 위해서는 다른 분기의 커밋 해시가 필요한 git cherry-pick hashhash이 필요합니다 .

전체 절차는 다음을 참조하십시오 : http://technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html


96

체리 픽이 필요한 상황의 짧은 예

다음 시나리오를 고려하십시오. 두 가지가 있습니다.

a) release1- 이 지점은 고객에게 제공되지만 여전히 해결해야 할 몇 가지 버그가 있습니다.

b)는 마스터 - 클래식 마스터 지점, 어디 당신이 할 수있는 release2에 대한 예를 들어 추가 기능에 대한.

지금 : 당신은 release1 에서 무언가를 고쳤습니다 . 물론 master 에서도이 수정이 필요합니다 . 그리고 그것은 체리 따기의 전형적인 유스 케이스입니다. 따라서이 시나리오에서 cherry pick은 release1 브랜치를 커밋 하여 마스터 브랜치에 포함시키는 것을 의미합니다 .


3
다른 방법이 필요할 수도 있습니다. 마스터에서 버그를 수정했으며 릴리스 1로 체리를 선택해야합니다. 또한 그것들은 가지보다는 저장소 일 수도 있습니다
canbax

1
왜 병합을 사용하지 않습니까?
FreeLightman

분기 해제 릴리스를 작성하고 분기에서 수정하고 릴리스에서 분기를 병합하고 마스터에서 릴리스를 병합하십시오.
Jasper-M

57

cherry-pick은 Git 기능입니다. 누군가가 한 분기의 특정 커밋을 대상 분기에 커밋하려면 cherry-pick이 사용됩니다.
git cherry-pick 단계는 다음과 같습니다.

  1. 대상 지점을 체크 아웃 (전환)합니다.
  2. git cherry-pick <commit id>
    

    여기서 커밋 ID는 다른 지점의 활동 ID입니다.

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. 목표 지점으로 미십시오

https://git-scm.com/docs/git-cherry-pick 방문


43

나는 체리 픽 이 하는 단계적인 그림 과이 그림애니메이션 (끝 근처)을 준비했습니다.

  1. 체리 따기 전에
    (우리는 지점 에서 커밋에 대한 체리 따기 를 할 것입니다 ) : Lfeature여기에 이미지 설명을 입력하십시오

  1. 명령 시작 git cherry-pick feature~2
    ( 이전 feature~2의 두 번째 커밋
    feature, 즉 commit L) : 여기에 이미지 설명을 입력하십시오

  1. 명령을 수행 한 후 ( git cherry-pick feature~2) : 여기에 이미지 설명을 입력하십시오

같은 애니메이션 : 여기에 이미지 설명을 입력하십시오


노트 :

커밋 L'사용자의 관점에서 (커밋 = 스냅 샷) 커밋 의 정확한 사본입니다 L.

기술적으로 (내부적으로), 그것은이다 , 새로운 다른이 (예를 들어,이 때문에 커밋 L에 대한 포인터가 들어 K부모 등을 (동안) L'포인터에 포함되어 있습니다 E).


분기 마스터에서 L '은 N-> M-> L입니까? 또는 마스터 브랜치에서 커밋 L을 독점적으로 가져옵니다
Priyank Thakkar

1
@ PriyankThakkar, 예, 독점적으로 L , 그 밖의 것은 없습니다 (그림 / 애니메이션에서 볼 수 있듯이).
MarianD

22

체리 픽이 리베이스와 비슷하거나 오히려 리베이스처럼 관리되는지 생각할 수 있습니다. 이것은 기존 커밋을 가져와 현재 지점의 헤드를 시작 지점으로 사용하여 다시 생성한다는 의미입니다.

A rebase는 부모 X가있는 커밋을 가져 와서 실제로 부모 Y가있는 것처럼 커밋을 재생성합니다. 이것은 정확히 무엇입니까 cherry-pick.

Cherry pick은 커밋을 선택하는 방법에 대한 자세한 내용입니다. pull(rebase)를 사용하면 git은 브랜치로 가져온 것 위에 로컬 커밋을 암시 적으로 재생성하지만 cherry-pick명시 적으로 커밋을 선택하고 현재 브랜치에서 암시 적으로 재생성합니다.

그래서 당신이하는 방식은 다르지만, 후드 아래에서 커밋의 재생과 매우 유사한 작업입니다.


1
나는 이것이 매우 유용한 것들이라고 생각합니다. 이유는 의미 cherry-pick목표 지점은 나중에 다시 소스 지점에 병합 때 수행하는 방식으로 동작합니다. 감사합니다.
Aluan Haddad

3
기능이 완료된 후 git merge 대신 cherry pick을 사용하고 싶습니다. 모두 기능을 완료하면 항상 git merge feature_branch를 수행합니다. cherry-pick 명령을 사용하지 않는 이유는 무엇입니까? 내가 체리 픽을 할 수 있다면 왜 스쿼시 커밋을 귀찮게 하는가
j2emanue

11

Copy (어딘가에서) 및 Paste (어딘가로)와 비슷하지만 특정 커밋의 경우입니다.

예를 들어 핫픽스를 수행하려는 경우이 cherry-pick기능을 사용할 수 있습니다 .

당신의 작업을 수행 cherry-pick개발 지점에, 그리고 merge그는 릴리스 브랜치에 커밋합니다. 마찬가지로 cherry-pick릴리스 브랜치에서 마스터로 작업을 수행하십시오. 짜잔


11

프로젝트에서 개발자 팀과 함께 작업하는 경우 여러 자식 분기 사이의 변경 사항을 관리하는 것은 복잡한 작업이 될 수 있습니다. 때로는 전체 브랜치를 다른 브랜치로 병합하고 싶지 않고 하나 또는 두 개의 특정 커밋 만 선택하면됩니다. 이 과정을 '체리 따기'라고합니다.

체리 따기에 대한 훌륭한 기사를 찾았습니다. 자세한 내용은 https://www.previousnext.com.au/blog/intro-cherry-picking-git 에서 확인하십시오.


7

커밋 ID없이 병합하려면이 명령을 사용할 수 있습니다

git cherry-pick master~2 master~0

위의 명령은 마지막 세 개의 커밋을 1에서 3으로 병합합니다.

단일 커밋에 대해이 작업을 수행하려면 마지막 옵션을 제거하십시오.

git cherry-pick master~2

이런 식으로 마스터의 끝에서 3 차 커밋을 병합합니다.


혼란 스럽습니다. 여기에 당신이 주인이 아닌 다른 지점에 있다고 생각합니다. 그리고 두 커밋을 언급했을 때 체리 피킹하려는 범위를 정의하기 위해 <from> 및 <to> 커밋을 참조합니다. 옳은? 시나리오가 설명되어 있으면 크게 도움이 될 것입니다. 그래도 좋은 추가. 감사.
Saurabh Patil

6

현재 커밋에 특정 커밋을 적용합니다.

이것은 다음을 의미합니다.

  • 이 커밋으로 추가 된 모든 파일이 추가됩니다
  • 이 커밋으로 삭제 된 모든 파일이 삭제됩니다
  • 이 커밋으로 수정 된 모든 파일이 병합됩니다. 이것은 커밋의 변경 뿐만 아니라 커밋 의 전체 파일 을 의미 합니다 !

예 : 커밋 A 고려

added newFileA
modified main:
+ import './newFileA'

커밋 B

added newFileB
modified main:
+ import './newFileB'

다른 지점에서 커밋 B선택 하면 다음 과 같이 끝납니다.

/newFileB
/main :
   import './newFileA'
   import './newFileB'

이후 B 커밋 포함 newFileB주요 ,하지만 newFileA , 버그의 결과를, 그래서 사용에주의.


0

공식 문서에서 발췌 :

하나 이상의 기존 커밋이 주어지면 각 커밋에 대한 변경 사항을 적용하고 각각에 대해 새로운 커밋을 기록하십시오. 이를 위해서는 작업 트리가 깨끗해야합니다 (HEAD 커밋의 수정 사항 없음).

변경 사항을 적용하는 방법이 확실하지 않은 경우 다음이 발생합니다.

  1. 현재 브랜치 및 HEAD 포인터는 마지막으로 커밋 된 상태로 유지됩니다.

  2. CHERRY_PICK_HEAD 참조는 적용하기 어려운 변경을 도입 한 커밋을 가리 키도록 설정됩니다.

  3. 변경 사항이 완전히 적용된 경로는 인덱스 파일과 작업 트리에서 모두 업데이트됩니다.

  4. 충돌하는 경로의 경우 인덱스 파일은 git-merge의 "TRUE MERGE"섹션에 설명 된대로 최대 3 개의 버전을 기록합니다. 작업 트리 파일에는 일반적인 충돌 마커 <<<<<<< 및 >>>>>>>로 묶인 충돌에 대한 설명이 포함됩니다.

다른 수정은 없습니다.

더 읽어보기 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.