Git
git cherry-pick

git cherry-pick 사용법 | 커밋 여러개, 충돌, 취소, 순서, 옵션, 예제 포함

이번 포스팅은 git cherry-pick 명령어를 다룹니다. 기본적인 설명과 사용법, 여러개 커밋 다루는 법, 충돌 관리, 순서, 다양한 옵션을 정리해보겠습니다.

1. git cherry-pick 이란?

Git 에서 Cherry picking 이란 어떤 브랜치에서 하나 이상의 원하는 커밋을 복사해서 다른 브랜치에 삽입하는 과정을 의미합니다. 사용하기에 따라 굉장히 강력하지만, 한 편으로는 히스토리를 복잡하게 만들 수도 있는 기능입니다. git cherry-pick 명령어로 사용할 수 있습니다.

특히, git cherry-pick 명령어는 긴급한 버그 수정이나 브랜치 간의 부분 코드 동기화 등에 사용합니다. 그 외의 경우에는 git merge git rebase 같이 협업 상황에서도 비교적 안전한 방법들을 우선적으로 고려하는 것이 좋은 프로세스입니다.

그럼, 꼭 필요한 경우에 바로 사용할 수 있도록 git cherry-pick 명령어의 사용법부터 제대로 이해해보도록 하겠습니다.

2. cherry-pick 사용법 기본

git cherry-pick 명령어의 사용법 자체는 간단합니다. 우선, 커밋을 삽입할 브랜치로 이동한 후, 다른 브랜치에서 가져올 커밋 ID 를 다음과 같이 입력해줍니다.

$ git cherry-pick [commit-id]

그러면, 해당 커밋과 같은 변경 사항을 가진 커밋이 현재 브랜치에 새로운 커밋을 등록됩니다.

예를 들어, 현재 아래와 같은 커밋 히스토리를 가지고 있다고 합시다.

A - B - C - D  main
 \ E - F - G  feature-a

이 때, main 브랜치에서 버그가 발견되었고, feature-a 브랜치에서 작업하던 개발자가 이 버그를 수정하는 커밋 Gfeature-a 브랜치에 생성했다고 가정합니다.

이때 서비스의 빠른 복구를 위해 커밋 G를 main 브랜치에 가져와야 합니다. 다음과 같이 git cherry-pick 명령어를 사용해서 해당 커밋을 추가합니다.

$ git cherry-pick [commit-id-G]

이 후, 커밋 히스토리는 다음과 같이 변경됩니다.

A - B - C - D - H  main
 \ E - F - G  feature-a

즉 커밋 G 의 모든 변경 사항이 커밋 H 라는 이름으로 새롭게 추가되었습니다.

3. 커밋 여러개 cherry-pick

여러 개의 커밋을 한 번에 가져오기 위해서는 2가지 방법을 사용할 수 있습니다.

3.1. 낱개로 가져오기

첫번째 방법은 커밋 하나씩 낱개로 입력해주는 방법입니다. 원하는 커밋 ID를 다음과 같이 하나씩 입력해줍니다.

$ git cherry-pick [commit-id-1] [commit-id-2] [commit-id-3]

git add 명령어 에서 여러 개의 파일 및 폴더를 추가할 때와 동일한 패턴입니다. 이 때, 앞에서부터 순서대로 새로운 커밋으로 추가됩니다.

3,2. 범위로 가져오기

두번째 방법은 가져올 커밋들의 범위를 지정해주는 방법입니다. 기호는 .. 혹은 ... 로 사용할 수 있으며, cherry-pick의 경우 2가지 모두 동일하게 취급합니다.

다음과 같이 사용하면 되며, 이 경우, [older-commit-id]는 제외되고 그 이후 커밋부터 포함되어 복사됩니다.

$ git cherry-pick [older-commit-id]..[new-commit-id]

만약, 섹션 2에서 봤던 feature-a 브랜치에서 커밋 FG를 가져오려면 다음과 같이 입력합니다.

$ git cherry-pick [commit-id-E]..[commit-id-G]

만약 [older-commit-id] 커밋도 포함하려면 ^.. 기호를 사용할 수도 있습니다. 즉 다음 명령어도 위 명령어와 같은 결과를 냅니다.

$ git cherry-pick [commit-id-F]^..[commit-id-G]

4. cherry-pick 충돌 해결 혹은 취소

git cherry-pick 명령어를 실행하면, 새로운 변경사항을 커밋하기 때문에 당연히 충돌 가능성이 존재합니다. 이 때는, merge 나 rebase 과정과 같이, 수동으로 충돌 해결 후에 Cherry picking을 이어가야 합니다.

이 과정은 rebase 와 동일한 패턴입니다. 수동으로 충돌을 해결한 이후에 다음의 2가지 옵션을 명령어와 함께 사용해서 Cherry picking을 완료하거나, 혹은 취소할 수 있습니다.

완료하기 위해서는 다음의 명령어를,

$ git cherry-pick --continue

취소하기 위해서는 다음의 명령어를 사용합니다.

$ git cherry-pick --abort

5. 자주 사용하는 옵션

다음은 git cherry-pick 명령어와 함께 자주 사용하는 명령어입니다. 가볍게 알아두었다가 필요한 경우에 명령어와 함께 사용해보세요.

5.1. 커밋하지 않고 기다리는 -n, --no-commit 옵션

git cherry-pick 명령어는 기본적으로 새로운 커밋 생성을 전제합니다. 하지만 때로는, 특정한 커밋을 가져오되, 또 다른 변경사항을 추가한 후에 커밋해야 할 때도 있습니다. 이를 위해선, cherry-pick 명령어가 생성한 커밋 그리고 또 하나의 커밋이 필요하겠죠.

-n 혹은 --no-commit 옵션은 이런 경우에 유용합니다. cherry-pick 명령어로 가져온 변경사항들을 커밋하지 않고 staging 상태에만 두기 때문입니다. 이 때문에, 별도의 커밋 없이 원하는 변경사항을 추가한 후, 한 번에 커밋할 수 있게 도와줍니다.

5.2. 커밋 메시지를 변경하는 -e, --edit 옵션

일반적으로, git cherry-pick 명령어는 자동으로 커밋 메시지를 생성하며 아래와 같은 형식을 갖습니다.

cherry-pick [commit-id] [commit-message-of-picked-commit]

만약 에디터를 열어서 이 커밋 메시지를 수정하거나, 더 많은 정보를 추가하고 싶다면 -e 혹은 --edit 옵션을 사용할 수 있습니다.

5.3. 가져온 커밋의 author 을 표시하는 --signoff 옵션

오픈소스 프로젝트나 협업하는 과정에서 cherry-pick 기능을 사용한다면, 가져온 커밋의 author를 표시하는 컨벤션을 정하는 경우가 많습니다.

이럴 경우 --signoff 옵션을 사용하면, 이전 커밋의 author 를 수동으로 작성할 필요 없이 커밋 메시지에 알아서 추가할 수 있습니다.

만약, 이전 커밋 메시지가 다음과 같았다면,

Implement new feature ABC

--signoff 옵션을 사용하여 cherry-pick한 새 커밋의 메시지는 아래와 같이 자동으로 작성됩니다.

Implement new feature ABC
Signed-off-by: Your Name [your.email@example.com]

5.4. 머지 전략을 지정하는 --strategy 옵션

병합 시 충돌 가능성이 존재하는 만큼, cherry-pick 명령어에도 머지 전략을 수동으로 지정할 수 있습니다. 현재 기본값인 ort 전략을 포함한 대표적인 머지 전략에 대한 내용은 git merge 포스트 마지막 섹션에 정리해두었습니다.

명령어는 다음과 같습니다.

$ git cherry-pick --strategy [merge-strategy]

6. 마치며

git cherry-pick 명령어는 프로젝트에 돌발상황이 발생했을 때 혹은 긴밀한 협업이 필요할 때, handy하게 사용할 수 있는 강력한 명령어입니다. 잘 익혀두었다가 적재적소에 활용할 수 있었으면 좋겠습니다.

copyright for git cherry-pick

© 2023 All rights reserved.