우아한테크코스-6th-FE/트러블슈팅

[트러블슈팅] 내 작업 브랜치 중간에 Merge된 동료의 작업물을 넣고 싶다면? (pull vs rebase)

Jaymyong66 2024. 8. 1. 15:10

상황은 이렇다.

우리 팀은 dev/fe 브랜치에서 각자 feature 브랜치 따서 작업을 하고 다시 dev/fe로 합치는 과정으로 진행한다. 

즉 dev/fe가 develop 브랜치이다.(Git flow 관점)

 

나는 로그인 기능을 개발하기 위해 dev/fe 브랜치에서 feat/authentication 브랜치를 따서 작업을 하고 있었다.

이후 동료의 디자인 토큰 기능과 헤더 기능이 완료가 되어 동료의 작업 브랜치에서 dev/fe 브랜치로 Merge가 되었다.

 

이때 나의 feat/authentication 브랜치로 최신의 dev/fe 브랜치의 작업물을 가져오고 싶은 상황이다.

Pull을 해야할까? Rebase를 해야할까?

 

그림 1 - 상황 재현

Rebase할 때 주의점

개념적인 Pull과 Rebase의 차이와 장단점은 다른 글에서 설명을 잘해주고 있으니 생략하겠다.

 

명심할 것은 Rebase를 원격 Repository의 브랜치 -> 로컬 브랜치로 하지만 않으면 된다는 것이다. (참고글 1, 참고글 2)

- 참고글 1 : 리모트 저장소에 푸시한 커밋은 리베이스하지 말 것

- 참고글 2 : rebase의 위험성

 

원격 Repository에서 로컬 브랜치로 Rebase를 한다면 각 커밋들이 그대로 내 로컬로 이동해오는 것이 아닌 커밋들이 복사되어 온다. 

그 말은 즉, Rebase 후 내 로그인 작업이 완료되어 다시 원격 Repository로 Push 할 때 Rebase로 온 커밋들의 해시값이 변경되어 내용은 같지만 해시값이 다른 커밋이 또 Push 된다는 것이다.

(로컬에서 로컬로 rebase 할 때는 커밋의 해시값이 동일한지는 아직 확인하지 못하였다.. 아마 원격 -> 로컬로 올때만 해시값이 바뀌지 않을까?)

 

원격 레포지토리의 커밋 히스토리에는 [동료의 커밋] - [내 작업 커밋] 순으로 올라가길 원했지만, [동료의 커밋] - [내 작업 커밋 + 복사된 동료의 커밋] 으로 중복되어 올라간다는 뜻이다.

 

결론은 Rebase로 처리를 하였다. 

그림 2 - Rebase를 할 경우
그림 3 - Pull을 할 경우

- 절차는 다음과 같다.

1. 작업 중인 브랜치에서 로컬의 dev/fe 브랜치로 이동한다.

2. upstream [dev/fe] -> 로컬 [dev/fe] 로 pull 받는다.

3. 작업 중이던 브랜치로 이동한다.

4. 로컬 [dev/fe] -> 로컬의 작업 브랜치로 rebase 한다.

git switch dev/fe

git pull upstream dev/fe

git switch feat/authentication

git rebase dev/fe

 

원격 브랜치 -> 로컬 브랜치로 rebase 하지 않고 로컬 브랜치 -> 로컬 브랜치 rebase 한다.

 

Conflict가 나요!!

만약 현재 작업 브랜치(feature 브랜치)에서 최신의 [dev/fe] (develop 브랜치) 로 rebase 하거나 Pull을 하거나 Conflict를  해결해야하는 것은 당연하다.

 

다만 이 두 방식의 Conflict 해결 방식이 다르다.

 

Pull의 경우, Merge 하는 과정에서 현재 작업 브랜치와 develop 브랜치의 모든 커밋 Conflict를 한번에 처리한다.

Rebase의 경우, 현재 작업 브랜치의 커밋이 develop 브랜치와 하나씩 비교되며 단계적으로 커밋 Conflict를 처리한다.

 

쉽게 말해 Rebase는 브랜치의 Base를 바꾸고, 그 이후에 내 현재 작업 브랜치의 커밋들이 하나씩 순차적으로 Conflict 를 해결한다는 것이다.

 

결과

커밋 히스토리가 최신의 develop 브랜치의 커밋 내역 위로 현재 내 작업 브랜치의 커밋 내역이 이쁘게 쌓인다!

그림 4 - 커밋 히스토리

 

잘못된 개념이 있다면 댓글 부탁드립니다.