여러 명이 관리하는 깃헙 레포에서는 다양한 일이 발생한다..
최근에 한 문제 상황을 cherry-pick CLI로 해결하여 이를 기록해보려 한다.
Diff
우선, 깃헙에서 코드 관리는 무조건 diff를 기준으로 업데이트한다. 레포의 기존 코드와 commit된 코드의 차이를 업데이트하는 것이다. commit된 코드를 레포의 기존 코드로 모두 덮어쓰기를 하지 않는다는 것을 유념해야 한다.
똑같은 소리 아닌가? 예를 들어 살펴보자.
레포에 dev, main 브랜치가 있고, 아래의 코드를 두 브랜치 공통 base 코드라고 가정해보자.
answer = 0
for i in range(10):
answer += i
print(answer)
이후 dev 브랜치에 아래의 두 커밋이 추가되었다.
answer = 0
for i in range(10):
# if i==0:
# continue
answer += i
print(answer)
answer = 0
for i in range(10):
if i==0:
continue
# else:
# print(answer)
answer += i
print(answer)

그림으로 나타내면 이런 상황이다.
다시 돌아가서, dev를 main으로 머지시킬 때 3번이 최종 커밋이라고 3번만 머지를 시키면 if문은 없고 else문만 있는 코드가 main의 최종 형태가 된다. 3번의 전체 코드로 덮어쓰기를 하는 것이 아니라 3번의 변경 사항만 main에 적용시킨다는 말이다.
즉, github는 기존과 신규의 Diff를 기준으로 코드를 업데이트시킨다.
cherry-pick
이제, 본론으로 들어가보자.
위의 그림과 마찬가지 상황이 벌어졌다. dev에 커밋 2개가 push되어 있었다. 그런데 첫번째 커밋은 아직 운영에 반영되면 안되고, 두번째 커밋은 hotfix로 바로 운영에 반영되어야 하는 상황이었다. 이렇게 커밋을 픽해서 머지시켜야 할 때 사용하는 것이 cherry-pick이다.
아래가 CLI 명령어이다. dev에서 반영한 두번째 커밋의 hash 값을 git log로 확인한다. main으로 checkout을 해주고 해당 hash 값으로 cherry-pick하면 적용이 완료된다.
git log
git checkout main
git cherry-pick [commit-Hash]
위의 diff를 현상황으로 이해해보자.
dev에는 첫번째 커밋과 두번째 커밋이 모두 반영되어 있으므로 if와 else문이 모두 있는 3번 코드이다. main에는 두번째 커밋의 diff만 적용됐으므로 else문만 있는 코드가 될 것이다.
만약, 두번째 커밋의 내용이 아래와 같이 if문을 지우고 else문만 작성한 형태라고 가정해보자.
answer = 0
for i in range(10):
# else:
# print(answer)
answer += i
print(answer)
똑같이 cherry-pick으로 main에 첫번재 커밋 말고, 두번째 커밋만 적용시키면 conflict가 발생할 것이다. 왜? 두번째 커밋의 내용이 if문을 지우는 것인데 main의 base에는 if문이 애초에 존재하지 않았기 때문이다. 이처럼 순차적으로 커밋을 적용시키지 않고, 예외적인 상황에서 cherry-pick으로 적용시킬 때에는 diff를 잘 파악하고 있어야 한다.
'DataHub' 카테고리의 다른 글
| DataHub 기본 구조 (2) | 2025.08.04 |
|---|---|
| 대규모 프로젝트에 디버깅툴 달기 (0) | 2025.01.01 |