안녕하세요. 이번 시간에는 git rebase를 할 때 쓸 수 있는 --onto 옵션에 대해 배워보겠습니다.

 


 현재 깃 branch가 다음과 같다고 해 보겠습니다. 2.txt add 라는 커밋에서부터 test 브랜치가 분기했습니다. 그런데, test bug.. 가 있어요. test 브랜치에 실수로 bug가 많은 커밋을 push해 버렸습니다. 이 commit으로부터 test2가 분기했습니다. test2는 1.txt에 무언가를 append 한 모양입니다.

 

 master에는 2.txt에 무언가를 추가했습니다.

 

 test bug.. 입니다. 3.txt에 It is bug feature라는 것이 추가되었습니다.

 

 다음에 1.txt에 무언가를 추가한 커밋입니다. test2에 붙어 있었습니다. 4와 5가 추가되었습니다.

 

 다음에, master에 2.txt에 append를 한 커밋입니다. 4, 5가 추가되었습니다. git rebase master test2 명령어를 입력해 보겠습니다.

 

 

 그러면 깃 그래프가 요래 그려집니다. 이 상황을 그림으로 그려보면 아래와 같습니다.

 

 원래 요래 된 상태였습니다. git rebase master test2를 하면, master의 head 뒤에 test2의 커밋들이 붙어버립니다. 여기까지는 알겠는데요. 어떤 커밋들이 붙을까요? reflog로 확인해 보겠습니다.

 

  pick test bug..와 pick append 1.txt가 보이네요. pick이 된 커밋들은, 회색으로 표시해 보겠습니다.

 

 회색 부분이 master의 head 뒤에 붙어버린 것입니다. 이는 분기가 된 2.txt add로부터 master의 변경 사항과 회색으로 칠한 부분의 변경 사항이 같지 않기 때문입니다. test bug..와 append 1.txt가 같이 끌려 나와서 아래와 같이 커밋이 생성될 수 밖에 없을 겁니다.

 

 

 중요한 것은 test bug.. 까지 그대로 들어갔다는 것입니다.

 


 다시 이 상황으로 돌아오겠습니다.

 

 우리는 test bug..를 빼고 단순하게 test2만의 변경 사항을 master의 뒤에 붙일 수 없을까요? 현재는 test 뒤에 붙은 상태입니다만, 이를 master로 옮기고 싶습니다.

 

 그럴려면 git rebase --onto master test test2를 입력하시면 됩니다. 이렇게 하면 어떻게 될까요?

 

 파란색으로 칠한 부분만 master의 뒤에 붙게 됩니다. 즉 주황색으로 칠해진 test의 커밋은 master의 뒤에 붙지 않습니다. test로부터 뻗어나온 test2의 커밋들이 붙게 됩니다.

 

 즉, test2가 더 이상 test에 의존적이지 않게 됩니다.

 

 

 예제를 하나 더 드리겠습니다. 깃 그래프가 요래 됩니다. 2.txt add로부터 master와 test가 뻗어나옵니다. 다음에 test로부터 test2가 뻗어나오고, test2로부터 test3이 뻗어나옵니다.

 

 이제 git rebase --onto master test test3을 입력하였습니다. 결과는 어떻게 나올까요? 일단, master의 뒤에 붙는 것은 맞습니다. 어느 커밋을 pick 하는지가 문제입니다.

 

 커밋은 이렇습니다. 일단, test3은 test2로부터 뻗어나왔고, test2는 test로부터 뻗어나왔기 때문에, test3은 test로부터 뻗어나왔습니다. 고로, test로부터 뻗어나온 군청색과 보라색의 커밋이 master 뒤에 붙게 됩니다.

 

 정말 그런지 볼까요? master 뒤에 append 1.txt와 add 4.txt가 붙었음을 볼 수 있습니다. 즉, git rebase --onto A B C인 경우, A 뒤에 B로부터 뻗어나온 C의 커밋들이 붙게 됩니다.