Cherrypick은 내가 Git을 제대로 공부해야겠다고 마음먹은 계기가 된 개념이다.
회사에서 Cherrypick에 대한 질문을 했는데 제대로 된 대답을 하지 못했었다.
체리픽(Cherry-pick)은 내가 원하는 다른 브랜치의 커밋을 선별하여 내 브랜치에 적용시키는 Git 기능을 의미한다.
체리픽에 대한 개념은 조금 어렵기 때문에 이미지를 통해 알아보자.
설명하기 앞서 beta 브랜치는 실제 서비스를 하기 전 베타 버전 코드를 올리는 브랜치이고 main 브랜치에는 실제 서비스로 제공하는 코드가 등록된다고 가정하자.
현재 main 브랜치와 beta 브랜치의 커밋은 위 이미지와 같은 상황이다.
beta 버전의 3번째 커밋까지 실제 서비스에 적용되어 있으며 4, 5, 6번째 beta 커밋은 아직 main 브랜치에 등록되지 않았다.
그런데 이 상황에서 실제 서비스에 문제가 발생하였다. 그리고 그 문제를 해결할 수 있는 코드가 위 이미지 중 노란색 커밋(5번째 커밋)에 존재한다고 가정해 보자.
아직 4번째 커밋과 6번째 커밋은 실제 서비스에 적용해도 될지 안될지 검증이 완료되지 않았다.
이런 상황이라면 4번째 커밋과 6번째 커밋을 무시한 채 오직 5번째 커밋의 변경사항을 main 브랜치에 연결시키고 싶을 것이다.
최종적으론 위 이미지와 같은 작업이 수행되어야 할 것이다.
이렇듯 이전 혹은 이후 커밋을 무시한 채 특정 커밋의 변경사항만을 "체리픽(Cherrypick)"을 통해 가져올 수 있는 것이다.
체리픽의 이름이 어디에서 나왔는지 안다면 조금 더 이해가 쉬울 것이다.
체리픽은 Cherry + pick의 합성어로 직역하자면 "체리를 고른다"라는 의미를 가진다.
이를 풀어 해석하면 체리를 수확할 때 내가 원하는 체리(상품성이 있는 체리나 먹을 수 있는 체리)만 선별하여 수확한다는 의미를 가지며 Git에서 또한 내가 따길 원하는 체리(커밋)를 선별한 후 가져온다는 의미에서 이런 이름을 지었다.
체리픽에서 주의할 점은 커밋 ID가 변경된다는 점이다.
체리픽은 특정 커밋을 원하는 브랜치의 가장 최신 커밋으로 가지고 오는데 이 때 커밋 ID를 새로 생성하게 된다.
즉, 체리픽을 할 커밋과 체리픽을 통해 브랜치의 가장 마지막에 붙은 커밋은 다른 커밋이라는 것을 알아두자.
그렇다면 이런 모호한 개념인 체리픽은 왜 사용할까?
위 예시에서 눈치챘을 수도 있겠지만 체리픽은 코드나 서비스에 문제가 발생하였을 경우 이를 해결하기 위해 많이 활용된다.
실제로 검증까지 끝난 커밋이더라도 실제 서비스 과정에서 문제가 발생하는 경우는 생각보다 자주 일어난다.
(사람은 신이 아니기에...)
이런 상황에서 문제를 먼저 해결하고 푸시 하기엔 main 브랜치의 커밋과 현재 커밋 사이에 검증되지 않은 기능을 가진 커밋이 main 브랜치에 반영되어 실제 서비스에 추가될 가능성이 있다.
만약 체리픽을 활용한다면 발생한 문제를 해결할 수 있는 커밋을 생성한 뒤 해당 커밋만 main 브랜치에 반영시키면 될 것이다.
그렇다면 검증되지 않은 커밋이 실제 서비스에 반영될 위험성이 매우 적어지므로 안전한 서비스 관리가 가능해질 것이다.
cherrypick_branch
브랜치를 생성한 후 해당 브랜치로 이동(checkout)하자.
2-1. cherrypick.md 파일 생성 & 파일 커밋
cherrypick_branch
마지막 커밋을 통해 cherrypick.md
파일이 추가되었음을 볼 수 있다.
2-2. Readme.md 파일 수정 & 커밋
이제 우리는 Cherrypick을 통해 첫번째 커밋의 cherrypick.md
파일은 가져오지 않고 README.md
파일의 변경 사항만을 가져올 것이다.
현재 브랜치는 main
이며 cherrypick_branch
에서 생성한 2개 커밋이 main
브랜치에 반영되지 않았음을 볼 수 있다.
이제 Cherrypick으로 가져올 커밋
이라는 메시지를 가진 커밋만 Cherrypick을 통해 main 브랜치에 가져와보자.
버튼을 클릭하면 main 브랜치에는 cherrypick.md
파일은 존재하지 않지만 "군침 싹~도는 커밋"이라는 README.md 파일에 추가한 문구가 반영되었음을 볼 수 있다.
즉, 성공적으로 cherrypick을 통해 원하는 커밋의 변경사항만을 가져왔음을 볼 수 있다.
cherrypick_branch에서 가져온 커밋과 main 브랜치에 추가된 커밋의 커밋 ID가 다른 것도 확인해보자.
만약 동일한 파일에 대해 2개의 커밋을 생성한 뒤 체리픽을 한다면 충돌이 날 것이다.
만약 동일한 파일에 2가지 변경 사항이 있는데 마지막 변경 사항만 가져오려 한다면 마지막 변경 이전에 생성된 변경 사항은 Git에서 어떻게 처리해야 하는지 도대체 알 수 없을 것이다.예를 들어 첫 번째 커밋에 "Hello"를 생성했고 두번째 커밋에 "World"를 생성한 후 두번째 커밋을 가져온다면 "World"를 가져와야 할지 "Hello"와 "World" 2가지 모두를 가져와야 할지 모호해질 것이다.
git cherry-pick [커밋 ID]
위에서 실습하며 알았겠지만 Cherrypick을 하기 위해선 일단 "Cherrypick을 통해 커밋을 가져올 브랜치"에 체크아웃이 선행되어 있어야 한다.
이후 내가 Cherrypick을 통해 가져오고 싶은 커밋 ID(해시 체크섬) 값을 확인 후 복사해 둬야 한다.
마지막으로 이 커밋 ID를 위 명령어에 넣으면 (충돌이 발생하지 않는 한) 성공적으로 Cherrypick이 가능하다.