안녕하세요🖐
오늘은 git rebase의 onto 옵션을 사용해본 경험을 공유합니다.
이 글을 통해 다음과 같은 인사이트를 얻으실 수 있습니다.
- git rebase onto 옵션에 대한 설명
- 어떤 경우에 사용하는가?
- 주의할점
rebase는 이름 그대로 base 브랜치를 변경해주는 명령어입니다.
--onto 옵션은
git rebase --onto <newbase> <upstream> [<branch>] 로 사용합니다.
인자가 3개나 된다니... 벌써 무서운 느낌이 들지만 차근차근 살펴보면 어렵지 않습니다.
위 명령을 말로 풀어보면
rebase해줘, newbase로, upstream부터 [branch]까지의 커밋을
로 해석할 수 있습니다.
현재 브랜치가 [branch]라면 마지막 인자는 생략 가능합니다.
다음과 같은 상황을 가정해볼게요.

main 브랜치는 production용 브랜치입니다.develop 브랜치는 개발용 브랜치입니다.feature-a 브랜치에서 작업한 내용을 main 브랜치에 병합하고자 합니다.develop 브랜치의 C, D 커밋은 main 에 반영되어선 안됩니다!우리가 잘 알고있는 rebase 명령어를 사용하면 어떻게 될까요?
$ git checkout feature-a
$ git rebase main

feature-a의 base 브랜치가 develop 이었기 때문에 원치 않는 결과가 되어버렸습니다.
develop의 C, D 커밋은 main에 넣지 않고, feature-a 브랜치의 커밋만 넣어 rebase 하고 싶을 때 --onto 옵션을 사용합니다.
$ git rebase --onto main develop [feature-a]
위 명령은 develop 브랜치부터 현재 체크아웃된 브랜치(feature-a)까지의 커밋들을 main 브랜치로 rebase합니다.
이 명령을 사용하면, develop 브랜치 이후에 현재 브랜치에 생성된 커밋들이 새로운 커밋 해시로 main 브랜치의 최신 커밋 뒤에 새롭게 배치됩니다.
깃 그래프는 다음과 같게 됩니다.

원하는대로 feature-a 브랜치의 커밋 세 개만 main 브랜치로 예쁘게 rebase 되었습니다.
Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라, 부모 커밋이 변경되므로 내용은 같지만 다른 커밋을 새로 만듭니다.
따라서 이미 push된 브랜치에 대해 rebase를 사용하게 되면 remote의 히스토리와 local 레포지토리의 히스토리가 불일치하게 되고,
remote와 local 사이에 많은 conflict가 뜨게 됩니다😮
소중한 팀원과 손절하고싶지 않다면 협업하는 상황에서는 꼭!
rebase가 필요한 commit 들은 push 하기전 local에서 처리하거나
신중히 사용하는게 좋겠습니다.