프로젝트가 복잡해지고 여러 기능이 동시에 개발되다 보면, 서로 다른 브랜치에서 작업한 내용을 하나로 통합해야 할 필요가 생깁니다.
Git은 이러한 브랜치 통합을 위한 다양한 도구와 전략을 제공합니다.
이 글에서는 대표적인 브랜치 간 병합 방법과, 세 가지 통합 방법인 merge, rebase, cherry-pick의 원리와 사용법을 살펴보겠습니다.
브랜치 간 병합 방법
Git에서 merge는 다양한 방식으로 병합을 지원합니다.
아래에서는 대표적인 네 가지 병합 방식인 Fast-forward, Recursive, Squash, Rebase & Merge에 대해 설명합니다.
브랜치 간 병합 방법에 대한 내용은 해당 글을 참고하여 작성했습니다.
Merge (Fast Forward)
Fast-forward 방식은 가장 기본적인 Merge 방식 입니다.
만약 기준 브랜치(main)가 병합할 대상 브랜치(feature)의 이전 커밋을 그대로 포함하고 있다면, Git은 별도의 병합 커밋을 만들지 않고 단순히 브랜치 포인터만 앞으로 빨리 감기(fast-forward) 하는 식으로 이동시킵니다.
이 방식은 커밋 히스토리를 간결하게 유지할 수 있다는 장점이 있어, 단일 개발자 환경이나 임시 브랜치를 병합할 때 주로 사용됩니다. 하지만 병합 히스토리가 남지 않기 때문에 협업 환경에서는 브랜치 병합 흐름을 추적하기 어렵다는 단점이 있습니다.
git checkout main
git merge my-branch # fast-forward로 자동 병합
→ 위의 예시에서 my-branch가 main 보다 앞선 커밋만 포함하고 있다면, 병합 시 main 포인터는 B → H로 바로 이동하며, 별도의 병합 커밋은 생성되지 않습니다.
장점
- 별도의 병합 커밋이 생성되지 않아 히스토리를 간결하게 유지할 수 있습니다.
- 변경 이력이 그대로 이어지므로, 추적이 쉽습니다.
단점
- 브랜치 간 작업 흐름이 기록되지 않아, 협업 이력이 남지 않습니다.
- 기능 단위의 작업 병합을 명확하게 표시하기 어렵습니다.
Merge(Recursive)
Recursive Merge는 Git이 두 브랜치를 병합할 때 가장 일반적으로 사용하는 방식입니다.
기준 브랜치와 병합할 브랜치가 서로 다른 경로의 커밋을 가지고 있을 경우, Git은 두 브랜치의 공통 조상 커밋을 기준으로 변경사항을 분석하고, 자동으로 병합합니다.
이때, 병합 커밋이 하나 생성되어 두 작업의 변경사항을 명확하게 남기게 됩니다.
git checkout main
git merge --no-ff my-branch
→ 이 방식은 브랜치 간의 작업 흐름을 명확하게 남기므로, 협업 시 특히 유용합니다.
장점
- 병합 커밋을 통해 기능 개발의 흐름이 명확하게 남습니다.
- 충돌이 발생해도 Git이 공통 조상 기준으로 처리해주어, 안정성이 높습니다.
단점
- 병합 커밋이 누적되면 커밋 히스토리가 복잡해질 수 있습니다.
Squash & Merge
Squash Merge는 기능 브랜치에서 진행된 여러 개의 커밋을 하나의 커밋으로 압축하여 병합하는 방식입니다.
실제로는 병합이 아니라 변경 내용을 Staging Area에 모은 다음, 사용자가 수동으로 하나의 커밋을 생성하게 됩니다.
이 방식은 커밋을 “작업 단위” 또는 “기능 단위”로 깔끔하게 남기고자 할 때 유용합니다.
예를 들어, 위의 그림과 같이 my-branch 브랜치에서 3개의 커밋으로 작업을 마쳤다면, main 브랜치에 병합할 때 하나의 커밋으로 정리해 넣을 수 있습니다.
git checkout main
git merge --squash my-branch
git commit -m "feat: 로그인 기능 추가"
장점
- 히스토리를 기능 단위로 정리할 수 있어 가독성이 좋고 관리가 용이합니다.
- 임시 커밋을 제거하고 최종 상태만 기록할 수 있습니다.
단점
- 세부 작업 이력이 사라지므로, 변경 흐름을 추적하기 어렵습니다.
- 누가 어떤 작업을 했는지 구분되지 않을 수 있습니다.
Rebase & Merge
Rebase Merge 방식은 협업 브랜치를 병합할 때, 커밋 히스토리를 깔끔하게 정리하기 위해 사용하는 방식입니다.
기능 브랜치의 커밋들을 기준 브랜치 위로 재배치(rebase)하여 선형 히스토리를 유지하며 병합 커밋 없이 적용됩니다.
예를 들어, main 브랜치에서 분기된 my-branch 의 커밋이 있는 경우, rebase 병합을 하게 되면, 별도의 병합 커밋 없이 선형적으로 적용됩니다.
이 방식을 GitHub, GitLab 등에서 PR(Pull Request) 병합 시 “Rebase and Merge” 버튼을 누르면 자동 적용되며, 커밋 하나하나를 보존하면서도 히스토리를 직선화하는 데 유리합니다.
git checkout my-branch
git rebase main
git checkout main
git merge my-branch
#만약 rebase 중 conflict 발생 시, conflict 관련 파일을 수정하고 진행
git rebase --continue
장점
- 병합 커밋 없이 히스토리가 선형적으로 유지됩니다.
- 모든 커밋 이력이 남아 디버깅이나 리뷰 시 유리합니다.
단점
- 충돌 발생 시 수동으로 해결이 필요하기 때문에, 협업 환경에서는 주의가 필요합니다.
- 커밋 순서를 유지하기 위해 체계적인 병합 규칙이 필요합니다.
merge – 브랜치 병합으로 통합하기
git merge
는 두 개 이상의 브랜치의 변경 내역을 하나의 브랜치로 합치는 명령어입니다.
보통 현재 체크아웃된 브랜치에 다른 브랜치의 변경 사항을 통합할 때 사용하며, 병합 커밋을 생성하여 분기와 통합 이력을 명확하게 남깁니다.
git merge <base_branch>
옵션 | 설명 |
--no-ff | fast-forward 병합 대신, 반드시 병합 커밋(merge-commit)을 생성합니다. |
--squash | 여러 커밋을 하나의 커밋으로 압축하며 통합하며, 자동커밋은 하지 않습니다. |
--commit | 병합 후 자동 커밋을 생성하도록 강제합니다.(default) |
git merge
를 사용하는 방법은 아래와 같습니다
# master 브랜치에 developer 브랜치를 병합하며, 병합 커밋을 생성
git checkout master
git merge --no--ff developer
rebase – 선형 히스토리로 정리하며 통합
rebase는 한 브랜치의 커밋들을 다른 브랜치의 최신 커밋 위에 "재적용"하는 방식으로 통합합니다.
이 과정에서 커밋 히스토리가 선형으로 정리되며, 불필요한 병합 커밋 없이 깔끔한 기록을 남길 수 있습니다.
git rebase <base_branch>
옵션 | 설명 |
-i / --interactive | Interactive 모드를 통해 커밋 순서 변경, 커밋 Squash, 편집 등을 할 수 있습니다. |
--onto | 특정 기준을 다르게 지정하여 커밋들을 재적용할 수 있습니다. |
--abort | rebase 진행 중 문제가 발생할 경우, 이전 상태로 되돌립니다. |
git rebase
를 사용하는 방법은 아래와 같습니다.
#developer 브랜치의 커밋들을 master 브랜치 위에 재적용
git checkout developer
git rebase master
#만약 rebase 중 conflict 발생 시, conflict 관련 파일을 수정하고 진행
git add app.js
git rebase --continue
#rebase 진행 취소
git rebase --abort
주의할 점
개인 작업 시 원격 저장소에 공유하기 전, 개인 브랜치에서 사용하면 커밋 히스토리를 깔끔하게 유지할 수 있습니다.
rebase는 기존의 커밋을 그대로 사용하는 것이 아닌, 내용은 같지만 새로운 커밋을 만들어 대체하기 때문에 이미 공유된 브랜치에서 rebase를 진행하면, 다른 팀원의 이력이 꼬일 수 있으므로 신중한 사용이 필요합니다.
cherry-pick – 선택적 커밋 통합
git cherry-pick은 특정 브랜치의 일부 커밋만 선택하여 현재 브랜치의 HEAD에 적용하는 명령어입니다.
필요한 버그 수정이나 기능 개선만을 별도로 반영할 때 유용하게 사용할 수 있습니다.
git cherry-pick <커밋_해시>
옵션 | 설명 |
--no-commit | 선택한 커밋의 변경 사항을 자동으로 커밋하지 않고, 워킹 디렉터리에 적용합니다. |
-x | 원본 커밋 해시를 커밋 메시지에 추가하여 출처를 기록합니다. |
git cherry-pick
을 사용하는 방법은 아래와 같습니다.
# master 브랜치에서 특정 커밋을 선택해 적용
git checkout master
git cherry-pick abc1234
#여러 커밋을 연달아 cherry-pick
git cherry-pick abc1234, dfg5678
#변경 사항만 적용한 후 나중에 검토하여 커밋할 경우
git cherry-pick --no-commit abc1234
git commit -m "message"
주의 할 점
- cherry-pick 은 특정 커밋을 이동하는 것이 아닌, 새로운 커밋으로 생성하는 것이기 때문에, 같은 커밋이 여러 번 쌓이는 일이 발생할 수도 있습니다.
- cherry-pick 하려는 커밋과 현재 브랜치 사이 conflict가 발생할 경우 아래의 방법으로 해결할 수 있습니다.
git add
로 수정된 코드를 다시 올린다. (커밋은 필요 없음)
이후 git cherry-pick --continue 명령어를 사용하면 다시 진행이 됩니다.
git cherry-pick --abort
명령어를 사용해cherry-pick
을 중단하면, 작업 이전의 상태로 돌아갈 수 있습니다.
브랜치 통합은 여러 개발 브랜치에서 작업한 내용을 하나의 일관된 히스토리로 정리하는 중요한 작업입니다.
이 글에서 다룬 merge, rebase, cherry-pick 명령어들의 특징과 활용법을 잘 이해하고, 프로젝트 상황에 맞게 전략적으로 적용한다면 효율적인 버전 관리와 협업 환경 구축에 큰 도움이 될 것입니다.
참고 링크
'DevOps > Git' 카테고리의 다른 글
[Git] 커밋 되돌리기 : reset, revert (0) | 2025.04.30 |
---|---|
[Git] Git 브랜치 전략 : 팀 환경에 맞는 전략 선택과 운영 방법 (0) | 2025.04.26 |
[Git] 브랜치 전략 이해 : branch, checkout, switch, restore, fetch (0) | 2025.04.19 |
[Git] 원격 저장소와 동기화 : fetch, pull, push (0) | 2025.04.18 |
[Git] 변경 이력 관리 : commit, log, diff, show (0) | 2025.04.17 |