CS

Merge & Rebase

머지도 대충 알고 리베이스도 대충 안다. 

근데 스쿼시 날리려고 할 때 리베이스가 안 될 때가 있고, 뭔가 꼬일 때도 있다.

확실히 머지와 리베이스를 정확히 알아야할 때다.

 

일단 머지부터!

$ git checkout master
Switched to branch 'master'
$ git merge iss53

c6 커밋은 c4, c5를 머지하여 생긴 새로운 커밋으로 c4, c5를 두개의 부모로 갖게 된다.

이때 c4와 c5를 판단하는 기준은 공통 부모인 c2가 된다. 이를 기준으로 c6 커밋을 만들게 된다.

 

만약 머지 중에 충돌이 났다는 것은 c2를 기준으로 같은 파일을 수정했다는 것이다.  

c3가 수정한 것을 c5가 수정했다면 문제가 생기지 않지만,

c4가 수정한 것을 c5가 수정했다면 충돌이 생긴다. 이때는 mergetool을 사용해서 충돌을 해결해줘야한다.

 

다음은 리베이스다.

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

Rebase는 특정 브랜치의 커밋들을 다른 브랜치에서 "다시" 재생하는 것이다. 

중요한 건 머지랑 결과물은 같지만 커밋 히스토리가 다르다.

먼저 새로 만들어지는 커밋이 c5가 아니라 c4'이다. 즉 완전히 새로운 커밋이 아니라,

기존 커밋에서 부모만 달라진 커밋이라는 것이다.

-> 현재 브랜치의 커밋의 부모는 리베이스하는 대상의 브랜치의 커밋이 된다.

그래서 결과적으로 순차적으로 커밋을 찍은 것처럼 히스토리가 변하게 되어 커밋 히스토리가 깔끔해진다.

$ git checkout master
$ git rebase experiment

* 위의 명령어를 치면 master 또한 c4' 커밋을 바라보고 있게 된다. (사실 부모가 똑같기 때문에 merge를 해도 완전히 똑같다.) 

만약 같은 상황에서 experiement(feature)에서 커밋이 하나 더 나가게 되면 이런 그래프를 그리게 된다.

당연히 실험 혹은 새로운 기능 추가 등은 master 브랜치보다 계속 그래프가 더 나가게 되는데, 

나중에 이를 master와 병합하면 아래와 그래프가 된다. 

그런데 여기서 feature 브랜치에서 커밋을 하나 더 찍으면 어떻게 될까?

여기서부터 약간 꼬이게 된다.

만약 여기서 f4가 commit ea994~ 기준으로 master와 같은 파일을 수정하지 않았다면 순조롭게 병합이 된다.

하지만 commit ea994 이후로 (정확히는 바로 그 이전 커밋 이후) master와 f4에서 동시에 수정하면

머지나 리베이스를 할 때 충돌이 나게 된다.

 

hello2까지 있었는데 master에서는 hello3를 추가했고, feature에서는 hello2를 삭제했다.

때문에 base기준으로 어떻게 수정해야할지 모르기 때문에 충돌이 발생하게 된다.

 

따라서 리베이스는 개발이 모두 끝나기 전까지는 하지 않는 것이 베스트. 

특히 완전히 release 되는 브랜치가 아니라 중간 중간 테스트를 위한 브랜치라면 더더욱,,,!

많은 브랜치가 머지되어 develop와 stage에 있는 복잡해보이는 그래프가 괴로워보이더라도,,,,

중간에 develop과 stage에서 리베이스를 하고, 또다시 개발을 진행하게 된다면

다른 사람과 코드가 꼬이는 게 아니라 내가 짠 코드 안에서도 충돌이 나서 불편한 상황이 발생할 수 있다.

또한 리베이스를 했을 때 develop과 stage를 의존해버리기 때문에 나중에 이 브랜치의 커밋을 되돌리거나,

재생성했을 때 곤란한 상황이 발생할 수 있다. 

 

또한 이미 dev나 stage에 push 한 커밋을 다시 rebase하는 것은 절대 금물이다.

내가 이미 dev나 stag에 푸쉬한 커밋들은 머지되어 팀원의 로컬에서 의존되었을 수 있다. 

하지만 그걸 없애고 다시 리베이스를 하게 된다면 이후 이걸 모르는 팀원이 pull을 했을 때

 

1. 내가 되돌리고자 했던 커밋을 포함한 커밋들이 찍히고

2. 같은 커밋(c4, c4')이 로그에 남기 때문에 더더욱 혼란스럽다.