[Git/Github] Git 심화 명령어2 — cherry-pick(특정 커밋 변경 적용하기)

dEpayse
dEpayse_publication
5 min readAug 6, 2022

이번 포스트에서는 특정 커밋의 변경 사항만을 적용시킬 수 있는 cherry-pick 에 대해 알아보자.

Fig1. cherry pick 예시

Fig1과 같은 상황을 가정해보자. branch_a 에서 만들었던 커밋 중 하나를 branch_b 에 적용시키고 싶다. 이럴 때 사용할 수 있는 명령어가 cherry-pick 이다. cherry-pick의 사전적인 의미로는 ‘자신에게 필요한 것만 선별적으로 택하다.’ 라는 뜻이 있다.

  • ‘git cherry-pick <커밋 id>’ : 특정 커밋의 변경사항만을 현재 브랜치에 적용한다.
  • ‘git cherry-pick <커밋 id1> <커밋 id2>’ : 특정 커밋 이력들의 변경사항만을 현재 브랜치에 적용하는 커밋을 생성한다. 물론 3개 이상의 커밋도 가능하다.
  • ‘git cherry-pick <커밋 id1>..<커밋 id2> : [커밋 id1] 에서 [커밋 id2] 까지의 이력들의 변경사항을 현재 브랜치에 적용하는 커밋을 생성한다.

cherry-pick 이후 conflict

cherry-pick 이후에도 conflict 가 발생할 수 있다. 현재 브랜치에서 파일 a의 첫 번째 줄을 수정한 커밋이 존재하고, cherry-pick 할 커밋도 파일 a의 첫 번째 줄을 수정했다면 conflict 가 발생할 수 있다. 또는 현재 브랜치에 적용할 두 커밋이 같은 파일의 같은 부분을 다르게 수정했다면 역시 conflict 가 발생할 수 있다.

conflict 를 해결할 수 있는 방법은 해당 파일의 충돌 부분을 수정하고 git add 를 통해 stage 에 올린 후에 다시 cherry-pick을 진행하면 된다. 만약 cherry-pick commit 이 생성되지 않은 상태에서 취소하고 싶다면, --abort 를 사용하여 revert 명령을 취소할 수 있다.

  • 충돌 발생시 충돌 해결 후 ‘git add <충돌 파일명>’ , ‘git cherry-pick --continue’로 cherry-pick 을 완료할 수 있다.
  • ‘git revert --abort’ : revert 명령어 이후 revert commit 이 생성되지 않은 상태에서는 cherry-pick 을 취소할 수 있다.

merge commit cherry-pick

한 브랜치에 다른 브랜치의 변경사항을 적용하여 생긴 merge commit 의 경우 cherry-pick 하면 브랜치의 커밋의 변경으로 적용할 것인지 명시해주어야 한다. 병합된 첫 번째 브랜치의 커밋에서 merge commit 으로의 변경 사항과, 병합된 다른 한 쪽의 브랜치의 커밋에서 merge commit 으로의 변경 사항은 다르기 때문이다. 이 때 ‘--mainline’ (‘-m’)이라는 옵션을 사용한다.

(git 에서 명령어의 옵션을 사용할 때 ‘ --<옵션명>’을 사용한다. 그러나 하나의 대시만 있는 경우, 이 옵션을 줄여서 간단하게 쓰겠다는 의미이다.)

Fig2. merge commit 을 cherry-pick 할 때 발생할 수 있는 문제점
  • git cherry-pick -m <parent-number> : merge commit 을 cherry-pick 할 때 parent-number 브랜치의 변경사항으로 적용한다.

여기서 parent-number 는 git log 로 cherry-pick 할 merge commit을 보면,

commit fea8e4b8d1c6f38228b58f7c75a6b9cc8651913e (HEAD -> master)
Merge: 1af4261 370a9bc
Author: author info
Date: some date

‘Merge : <커밋1 id> <커밋2 id>’ 부분을 볼 수 있는데, 왼쪽부터 parent-number 1번으로 시작하여 오른쪽 방향으로 1씩 증가한다. 즉 예시에서는 1af4261 이 parent-number 1번, 370a9bc 가 parent-number 2번이다.

fea8e4b 커밋을 cherry-pick 하고 1af4261 커밋에서 fea8e4b 커밋에 적용된 변경사항을 적용하고 싶을 땐 다음과 같이 명령어를 작성할 수 있다.

git cherry-pick -m 1 fea8e4b

유용한 revert options

  • --edit (-e) : git cherry-pick 을 사용하면 기본적으로 설정되어 있는 템플릿으로 커밋을 수행하지만, 커밋 메세지를 명시적으로 정하여 커밋할 수 있다.
  • --no-commit (-n) : git cherry-pick 명령어 이후 충돌이 없을 경우 기본적으로 커밋을 생성하지만, 이 옵션을 사용하면 변경사항을 Working tree 에만 적용하여 stage 에 올린다.

cherry-pick 에 대한 일반적 견해

cherry-pick 은 그렇게 권장되는 명령어는 아니다. 같은 내용의 변경 사항인데도 다른 커밋으로 생성되기 때문에 커밋 이력 관리가 어려워질 수 있기 때문이다.

그럼에도 cherry-pick 은 특정 커밋의 변경사항만 적용할 수 있다는 이점이 있기에 필요시 사용할 수 있을 것이다.

Reference

  1. [Git official — Book] — https://git-scm.com/book/en/v2
  2. [불곰] “[Git] 체리픽 (Cherry-pick)” — https://brownbears.tistory.com/606
  3. [삐멜 소프트웨어 엔지니어] “git 명령어 : git cherry-pick” — https://cselabnotes.com/kr/2021/03/31/56/
  4. [기계인간 John Grib] “git cherry-pick” — https://johngrib.github.io/wiki/git/cherry-pick/

--

--

dEpayse
dEpayse_publication

나뿐만 아니라 다른 사람들도 이해할 수 있도록 작성하는, 친절한 블로그를 목표로.