git-rebase의 onto 옵션, 어떤 경우에 사용하는 것인가?
Table of Contents
Mermaid 다이어그램이 보이지 않을 경우, https://driip.notion.site/git-rebase-onto-3e2061788e6c4519be3555b5afeab30b 링크에서 읽어 주시면 감사하겠습니다.
기본적인 git-rebase에 대하여
git-rebase는 기본적으로 1개 또는 2개의 인자를 받는다. 전체 Signature는 git rebase <upstream> [<branch>]이다.
gitGraph commit id: "A" commit id: "B" branch topic commit id: "C" commit id: "D" checkout main commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
1개의 인수를 전달하는 경우
Signature는 git rebase <upstream>이다.
가령 main branch에 topic branch를 rebase하고 싶다면, 현재 branch가 topic인 상황에서 git rebase main를 입력하면 된다.
$ git branch --show-current
topic
$ git rebase main
Successfully rebased and updated refs/heads/topic.
Shell
복사
gitGraph commit id: "A" commit id: "B" commit id: "E" commit id: "F" commit id: "G" branch topic commit id: "C'" commit id: "D'"
Mermaid
복사
2개의 인수를 전달하는 경우
Signature는 git rebase <upstream> <branch>이다.
현재 branch가 topic이 아닌 상황에서 git rebase master topic을 입력해도 위와 똑같은 결과를 얻을 수 있다.
$ git rebase master topic
Successfully rebased and updated refs/heads/topic.
Shell
복사
gitGraph commit id: "A" commit id: "B" commit id: "E" commit id: "F" commit id: "G" branch topic commit id: "C'" commit id: "D'"
Mermaid
복사
이는 결국 git switch <branch> 후 git rebase <upstream>을 수행하는 것과 동치이다.
--onto <newbase> 옵션
git-rebase에는 다양한 옵션을 제공할 수 있는데, 그 중 하나가 --onto 옵션이다. 이를 사용할 경우 Signature는 git rebase --onto <newbase> <upstream> [<branch>]가 된다.
인자가 2개 내지는 3개로 늘어나서 당황스러울 수 있겠다. 이 옵션을 쉽게 설명하면, “<newbase>와 <upstream>이 동일한 커밋을 가리킨다고 인정하고, 현재 branch를 <newbase>에 rebase하는 것”이라 할 수 있겠다.
아래는 Git 공식 문서에서 제공하는 --onto 옵션을 사용하는 예시이다.
예시 1
다음과 같은 상황을 가정하자.
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" branch topic commit id: "E" commit id: "F" commit id: "G" checkout main commit id: "H" commit id: "I" commit id: "J"
Mermaid
복사
topic branch를 main으로 rebase하고 싶다면 어떻게 하면 될까?
그냥 rebase
아마 통상적인 rebase로는 다음과 같이 원치 않았던 결과가 나올 것이다.
$ git branch --show-current
topic
$ git rebase main
Successfully rebased and updated refs/heads/topic.
Shell
복사
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" checkout main commit id: "H" commit id: "I" commit id: "J" branch topic commit id: "C'" commit id: "D'" commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
rebase --onto
아마 우리가 원하는 결과는 아래와 같은 결과가 아니었을까? 이는 다음과 같이 --onto 옵션을 이용하면 만들 수 있다.
$ git branch --show-current
topic
$ git rebase --onto main next
Successfully rebased and updated refs/heads/topic.
Shell
복사
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" checkout main commit id: "H" commit id: "I" commit id: "J" branch topic commit id: "E'" commit id: "F'" commit id: "G'" checkout main
Mermaid
복사
예시 2
이번에는 다음과 같은 상황을 가정하자.
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" branch topic commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
이번에도 하고 싶은 건 똑같다. topic branch를 main으로 rebase하고 싶다면 어떻게 하면 될까?
그냥 rebase
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" checkout main branch topic commit id: "C'" commit id: "D'" commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
rebase --onto
gitGraph commit id: "A" commit id: "B" branch next commit id: "C" commit id: "D" checkout main branch topic commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
실전 예시
다음과 같은 상황을 가정하자.
•
Initial branch로 main branch가 존재한다.
•
main을 parent branch로 하는 dev branch가 존재한다.
•
dev를 parent branch로 하는 feat/1 branch가 존재한다.
위 상황과 더불어, 우리는 feat/1 branch에서 작업하고 있고, dev나 main branch는 수시로 commit이 추가되거나 다른 branch에 rebase될 수 있다고 가정하자.
gitGraph commit id: "A" commit id: "B" branch dev commit id: "C" commit id: "D" branch feat/1 commit id: "E" commit id: "F" commit id: "G"
Mermaid
복사
단순한 rebase로 해결되는 상황
feat/1 branch에서 작업하던 도중, 이의 parent branch인 dev branch에 새 commit이 추가되었고, feat/1 branch에 이를 반영할 필요가 생겼다.
gitGraph commit id: "A" commit id: "B" branch dev commit id: "C" commit id: "D" branch feat/1 commit id: "E" commit id: "F" commit id: "G" checkout dev commit id: "H" commit id: "I"
Mermaid
복사
보통 이런 경우는 단순한 rebase로 해결할 수 있다.
$ git branch --show-current
feat/1
$ git rebase dev
Successfully rebased and updated refs/heads/feat/1.
Shell
복사
gitGraph commit id: "A" commit id: "B" branch dev commit id: "C" commit id: "D" commit id: "H" commit id: "I" branch feat/1 commit id: "E'" commit id: "F'" commit id: "G'" checkout dev
Mermaid
복사
rebase --onto가 필요한 상황
위 상황에 이어, main branch에 새로운 commit이 추가되었다고 해 보자.
gitGraph commit id: "A" commit id: "B" branch dev commit id: "C" commit id: "D" commit id: "H" commit id: "I" branch feat/1 commit id: "E'" commit id: "F'" commit id: "G'" checkout main commit id: "J"
Mermaid
복사
그리고 dev branch에서 해당 커밋이 필요해서 main branch에 rebase했다고 해 보자. 아마 다음과 같은 그림이 나올 것이다.
gitGraph commit id: "A" commit id: "B" checkout main branch feat/1 order: 2 commit id: "C" commit id: "D" commit id: "H" commit id: "I" commit id: "E'" commit id: "F'" commit id: "G'" checkout main commit id: "J" branch dev order: 1 commit id: "C'" commit id: "D'" commit id: "H'" commit id: "I'" checkout main
Mermaid
복사
빨리 feat/1 branch를 어떻게든 해야 할 것만 같다. 우리가 해야 하는 것은 “dev의 HEAD commit(I’)과 (feat/1의) I commit이 동일하다는 것을 인정하고, feat/1을 dev로 rebase하는 것”이다.
그리고 이는 rebase --onto로 해결할 수 있다.
$ git branch --show-current
feat/1
$ git rebase --onto dev I
Successfully rebased and updated refs/heads/feat/1.
Shell
복사
gitGraph commit id: "A" commit id: "B" commit id: "J" branch dev commit id: "C'" commit id: "D'" commit id: "H'" commit id: "I'" branch feat/1 commit id: "E'" commit id: "F'" commit id: "G'" checkout main
Mermaid
복사