영주의 개발노트
🏦 기술 부채 상환 | git merge 와 rebase에 대해 알아보자 (2) 본문
🏦 기술 부채 상환 | git merge 와 rebase에 대해 알아보자
최근 두고두고 쌓아둔 업보가 거대한 눈덩이로 변해 나를 덮쳤었다. 이 경험을 소개하며 그동안 쌓여온 git에 대한 기술 부채를 조금 갚아보려 한다. mac 세팅 중 사내 문서를 참고하여 아래 명령
0juuu.tistory.com
지난번에 merge와 rebase 개념에 대해 알아보았다. 이번에는 두 방식의 차이와 내가 겪었던 문제에 대한 원인과 어떻게 해결할 수 있을지에 대해 이야기해보겠다.
Merge
merge는 두 개의 브랜치와 합칠 두 브랜치의 공통 조상 브랜치를 기준으로 합치게 된다. 이 과정에서 새로운 병합 커밋이 생성되며, 두 브랜치의 히스토리는 그대로 유지된다.
- 특징 : 브랜치의 전체적인 히스토리가 보존되고, 합쳐지는 이력이 커밋으로 남기에 병합되는 지점이 명확히 표시된다. 그렇기에 병합되는 과정에서 일어나는 충돌 위치를 쉽게 파악할 수 있다. 이를 비파괴적이라고 한다. 더 자세히 설명하자면 두 브랜치의 변경사항을 병합할 때 새로운 커밋이 추가될 뿐, 원래 커밋 히스토리는 수정되거나 삭제되지 않는다. 이러한 특성 덕분에 브랜치 구조와 이력을 유지 및 보존할 수 있다.
- 단점 : merge 시 매번 새로운 커밋을 만들기 때문에 커밋 로그가 길고 복잡해질 수 있다. 이는 여러 브랜치가 생성되고 합쳐졌을 때 진가를 발휘하게 된다. merge 시 매번 새로운 커밋을 추가하면, 프로젝트의 히스토리가 분기와 병합으로 얽혀 가시성이 떨어지고 관리하기 힘들어질 수 있다.
Rebase
rebase는 한 브랜치의 커밋들을 다른 브랜치 끝에 재배치한다. 예를 들어 현재 내 개발 브랜치를 main 브랜치로 rebase 한다면, main 브랜치의 변경사항이 먼저 반영되고 그 뒤 내가 개발한 커밋들이 순서대로 재작성된다.
- 특징 : 키포인트는 재작성된다는 것이다. 기존 커밋이 새로운 커밋으로 다시 작성되면 고유 식별자인 커밋의 해시가 변경된다. 이로 인해 커밋 이력이 깔끔한 선형 형태로 정리된다. 별도의 병합 커밋 없이 히스토리를 유지할 수 있다.
- 단점 : 커밋이 재작성됨으로써 이력이 변경되기 때문에 이미 공유된 브랜치에 rebase를 실행하게 되면 여러 혼란을 야기할 수 있다. 예를 들어, 기존 이력과 새 이력 간의 충돌을 해결해야 할 수도 있고 rebase 후 원격 브랜치에 git push --force 라는 명령어로 강제 푸시를 해야 하는 상황이 생길 수 있다. 이는 다른 사람의 커밋이 덮어쓰기 되는 위험성을 초래한다.
둘 다 장단점이 존재하기 때문에 어느 것이 더 좋다고 말할 수는 없을 것 같다. 협업하며 git을 사용한다고 가정하였을 때, 개인적인 견해로는 rebase를 사용하지 않을 것 같다. rebase는 커밋 이력이 사라질 수 있다는 특성을 가지고 있기 때문이다. merge와 rebase에 대해 알아보았으니 이제 내가 겪은 상황에 대한 원인과 어떻게 하면 해결할 수 있었을지에 대해 얘기해보고자 한다.
문제 상황 분석
git config --global pull.rebase true 로 설정을 하였기에 기본적으로 pull을 하면 rebase 방식으로 가져오게 된다. 따라서 개발 브랜치에서 git pull origin develop 명령을 실행할 때 develop 브랜치의 모든 변경사항이 새로운 커밋으로 재작성된다. 내용은 같다 하더라도 새로운 커밋으로 쓰여졌기 때문에 develop으로의 pull request 시, 변경사항에 들어가게 된 것이다.
해결 방안
어떻게 하면 이러한 불상사를 막을 수 있을까? ChatGPT에게 도움을 요청하였고, 아래 3가지의 방법을 제안해주었다.
- 설정 변경
rebase 방법을 아예 사용하지 않는 것이다. git config --global pull.rebase false로 pull 시 기본 merge가 되도록 설정할 수 있다. - 명령어 수정
필요할 때, git pull --no-rebase origin develop 명령을 사용하여 pull 시 rebase 말고 merge 방식으로 병합할 수 있다. - 이전 상태 복구
이미 PR에 잘못된 커밋이 올라갔다면, git reset --hard로 이력을 정리한 후, git push --force로 PR을 업데이트해 불필요한 커밋을 제거할 수 있다. 하지만, git push --force는 강제로 원격 브랜치를 덮어쓰기에 일부 작업 사항이 날아갈 수 있다는 점을 명심해야 한다.
기본적으로 rebase를 사용함으로써 생긴 문제이므로 merge 하는 방식으로 해결할 수 있다고 제안해 준 것을 볼 수 있다.
마치며
위 해결방안에서 말했듯이 rebase로 생긴 문제를 미연에 방지하려면 merge 방식을 사용하라고 한다. 이 글을 정리하면 할수록 더더욱 rebase를 왜 사용하는지 모르겠다... 심미성을 위해 잃는 것이 너무 많은 것 같다. 우선은 사내 기준대로 rebase를 사용하긴 하겠지만, 문제를 해결할 때에는 merge 방식을 택하여 해결할 것 같다. 아직 공부가 덜 된 것인지... 이 글을 읽는 사람들에게 신랄한 피드백을 요청한다... 🙇♀️
'STUDY 📖' 카테고리의 다른 글
Elasticsearch 데이터 타입에 대해 알아보자 (0) | 2025.02.15 |
---|---|
gRPC와 Protocol Buffers에 대해 알아보자 (2) - Protocol Buffers (1) | 2025.01.14 |
gRPC와 Protocol Buffers에 대해 알아보자 (1) (2) | 2024.12.04 |
🏦 기술 부채 상환 | git merge 와 rebase에 대해 알아보자 (0) | 2024.11.06 |
검색개발을 한다는 것 (feat. 기존 도메인 vs 검색 도메인) (0) | 2024.10.24 |