Close

Git 병합

병합은 Git의 포크된 기록을 다시 통합하는 방법입니다. git merge 명령을 사용하면 git 브랜치가 만든 독립적인 개발 라인을 단일 브랜치로 통합할 수 있습니다.

아래에 제시된 모든 명령은 현재 브랜치에 병합됩니다. 병합을 반영하도록 현재 브랜치가 업데이트되지만 대상 브랜치는 전혀 영향을 받지 않습니다. 다시 말하지만, git merge 명령은 종종 git checkout 명령과 함께 사용되어 현재 브랜치를 선택하며, git branch -d와 함께 사용되어 사용되지 않는 대상 브랜치를 삭제합니다.


작동 방식


git merge는 여러 커밋 시퀀스를 하나의 통합된 기록으로 결합합니다. 가장 빈번한 사용 사례에서 git merge 명령은 두 브랜치를 결합하는 데 사용합니다. 문서의 다음 예제에서는 이 브랜치 병합 패턴을 중점적으로 다룹니다. 이 시나리오에서 git merge는 두 개의 커밋 포인터(보통 브랜치 팁)를 사용하며 두 포인터 간에 일반적인 기준 커밋을 찾습니다. Git은 일반적인 기준 커밋을 찾으면 대기 중인 각 병합 커밋 시퀀스의 변경 사항을 결합하는 새 '병합 커밋'을 만듭니다.

main 브랜치를 기준으로 하는 새로운 브랜치 기능이 있다고 가정합니다. 이제 이 기능 브랜치를 main에 병합하려고 합니다.

feature 브랜치를 main에 병합
콘솔 창
관련 자료

고급 Git 로그

Bitbucket 로고
솔루션 보기

Bitbucket Cloud에서 Git에 대해 알아보기

이 명령을 호출하면 지정된 브랜치 기능이 현재 브랜치에 병합되는데, 이것을 main이라고 가정하겠습니다. Git은 병합 알고리즘을 자동으로 결정합니다(아래에서 설명).

새 병합 커밋 노드

병합 커밋은 상위 커밋이 두 개 있다는 점에서 다른 커밋과 구별됩니다. 병합 커밋을 만들 때 Git은 사용자를 위해 별도의 기록을 자동으로 병합하려고 시도합니다. Git이 두 기록에서 변경된 데이터 조각을 발견하면 자동으로 결합할 수 없습니다. 이 시나리오는 버전 제어 충돌이며 Git이 작업을 계속하려면 사용자 개입이 필요합니다.

병합 준비


병합을 수행하기 전에 원활한 병합을 진행하기 위해 몇 가지 준비 단계를 거쳐야 합니다.

수신 브랜치 확인


git status를 실행하여 HEAD가 올바른 병합 수신 브랜치를 가리키는지 확인합니다. 필요한 경우 git checkout 을 실행하여 수신 브랜치로 전환합니다. 이 경우 git checkout main을 실행합니다.

최신 원격 커밋 가져오기


수신 브랜치 및 병합 브랜치가 최신 리모트 변경 사항으로 업데이트된 최신 상태인지 확인합니다. git fetch를 실행하여 최신 원격 커밋을 가져옵니다. 가져오기가 완료되면 git pull을 실행하여 main 브랜치가 최신으로 업데이트되었는지 확인합니다.

병합


앞서 설명한 "병합 준비" 단계를 수행하면 git merge 을 실행하여 병합을 시작할 수 있습니다. 여기서 은 수신 브랜치에 병합할 브랜치의 이름입니다.

빨리 감기 병합


현재 브랜치 팁에서 대상 브랜치까지의 선형 경로가 있는 경우 빨리 감기 병합이 발생할 수 있습니다. 브랜치를 "실제로" 병합하는 대신, Git은 현재 브랜치 팁을 대상 브랜치 팁까지 이동시키는 작업만으로(즉, "빨리 감기") 기록을 통합할 수 있습니다. 대상 브랜치에서 연결할 수 있는 모든 커밋을 이제 현재 커밋을 통해 사용할 수 있으므로 기록이 효과적으로 결합됩니다. 예를 들어, 일부 기능을 main 브랜치로 빨리 감기 병합하면 다음과 같습니다.

메인 노드 앞 및 빨리 감기 후 기능 노드의 노드는 모두 동일한 노드에 있습니다

그러나 브랜치가 분기한 경우에는 빨리 감기 병합이 불가능합니다. 대상 브랜치에 대한 선형 경로가 없는 경우 Git은 3방향 병합을 통해 결합할 수밖에 없습니다. 3방향 병합은 전용 커밋을 사용하여 두 기록을 연결합니다. 3방향 병합이라는 이름은 Git이 브랜치 팁 두 개와 공통 원형 등 세 개의 커밋을 사용하여 병합 커밋을 만든다는 점에서 유래합니다.

3방향 병합 후의 다이어그램

이 병합 전략 중 무엇이든 사용할 수 있지만 많은 개발자는 작은 기능이나 버그 수정에는 빨리 감기 병합(rebase를 통해 제공)을 사용하고 장기 실행 기능을 통합할 때는 3방향 병합을 사용하는 편입니다. 후자의 경우 결과적으로 병합 커밋은 두 브랜치의 상징적 결합으로 사용됩니다.

첫 번째 예제는 빨리 감기 병합을 보여줍니다. 아래 코드는 새 브랜치를 만들고, 브랜치에 커밋 두 개를 추가한 다음, 빨리 감기 병합을 통해 메인 라인에 통합합니다.

# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature

이것은 장기 실행 기능용 조직 도구보다 개별적인 개발로 더 많이 사용되는 단기 토픽 브랜치의 일반적인 워크플로입니다.

또한 새로운 기능은 이제 메인 브랜치에서 액세스할 수 있기 때문에 Git의 git branch -d에서 오류가 발생하지 않습니다.

빨리 감기 병합 동안 기록을 유지하기 위해 병합 커밋이 필요한 경우 --no-ff 옵션을 사용하여 git merge를 실행할 수 있습니다.

git merge --no-ff <branch>

이 명령은 지정된 브랜치를 현재 브랜치에 병합하지만 항상 병합 커밋을 생성합니다(빨리 감기 병합인 경우에도). 리포지토리에서 발생하는 모든 병합을 문서화하는 데 유용합니다.

3방향 병합


다음 예제는 매우 유사하지만 기능이 진행되는 동안 main 브랜치가 진행되므로 3방향 병합이 필요합니다. 대규모 기능이나 여러 개발자가 동시에 프로젝트를 작업할 때 흔히 발생하는 시나리오입니다.

Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

백트래킹 없이는 mainnew-feature로 이동할 방법이 없기 때문에 Git이 빨리 감기 병합을 수행하는 것은 불가능합니다.

대부분의 워크플로에서 new-feature는 개발하는 데 시간이 오래 걸리는 훨씬 더 큰 기능이며, 이것은 그동안 main 브랜치에 새 커밋이 나타나는 이유입니다. 기능 브랜치가 실제로 위의 예제와 같이 작은 경우 main 브랜치로 다시 지정(rebase)하고 빨리 감기 병합을 수행하는 것이 더 나을 수 있습니다. 이렇게 하면 불필요한 병합 커밋이 프로젝트 기록을 어지럽히지 않도록 방지할 수 있습니다.

충돌 해결


병합하려는 두 브랜치가 동일한 파일의 동일한 부분에서 변경되면 Git은 어떤 버전을 사용해야 하는지 알 수 없습니다. 이런 상황이 발생하면 병합 커밋 직전에 중지되므로 수동으로 충돌을 해결할 수 있습니다.

Git의 병합 프로세스에서 가장 좋은 점은 익숙한 편집/스테이지/커밋 워크플로를 사용하여 병합 충돌을 해결한다는 것입니다. 병합 충돌이 발생한 경우 git status 명령을 실행하면 해결해야 할 파일이 표시됩니다. 예를 들어, 두 브랜치가 모두 hello.py의 동일한 섹션을 수정한 경우, 다음과 유사하게 표시됩니다.

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

충돌을 표시하는 방식


병합 중에 충돌이 발생하면, Git은 충돌한 콘텐츠의 양쪽을 표시하는 시각적 표시기를 사용하여 영향을 받는 파일의 콘텐츠를 편집합니다. 시각적 마커는 <<<<<<<, ======= 및 >>>>>>>입니다. 병합하는 동안 프로젝트에서 이 표시기를 검색하여 충돌을 해결해야 하는 위치를 찾는 것이 좋습니다.

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;

일반적으로 ======= 마커 앞의 콘텐츠는 수신 브랜치고 마커 뒤의 부분은 병합 브랜치입니다.

충돌하는 부분을 확인한 후에는 원하는 대로 병합을 수정할 수 있습니다. 병합을 완료할 준비가 되면 충돌하는 파일에서 git add 명령을 실행하여 Git에 충돌이 해결되었음을 알리기만 하면 됩니다. 그런 다음 일반 git commit을 실행하여 병합 커밋을 생성합니다. 일반 스냅샷을 커밋하는 것과 동일한 프로세스이므로 일반 개발자는 자신의 병합을 쉽게 관리할 수 있습니다.

병합 충돌은 3방향 병합인 경우에만 발생합니다. 빨리 감기 병합에서는 충돌하는 변경 사항이 있을 수 없습니다.

요약


이 문서는 git merge 명령에 대한 개요입니다. 병합은 Git으로 작업할 때 필수 프로세스입니다. 앞서 병합의 내부 메커니즘, 빨리 감기 병합과 3방향 병합의 차이, 참(true) 병합에 대해 살펴봤습니다. 주요 내용은 다음과 같습니다.

1. Git 병합은 커밋 시퀀스를 하나의 통합된 커밋 기록으로 결합합니다.

2. Git을 병합하는 두 가지 주요 방법은 빨리 감기 병합과 3방향 병합입니다.

3. 두 커밋 시퀀스에서 충돌하는 변경 사항이 없으면 Git은 커밋을 자동으로 병합할 수 있습니다.

이 문서는 git branch, git pullgit fetch와 같은 다른 Git 명령어를 통합하고 참조했습니다. 자세한 내용은 해당하는 별도의 페이지를 참조하세요.


이 문서 공유
다음 토픽

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

도구로 가득한 벽을 사용하여 협업하는 사람들

Bitbucket 블로그

DevOps 일러스트레이션

DevOps 학습 경로

Atlassian 전문가와 함께 하는 Demo Den 기능 데모

Bitbucket Cloud가 Atlassian Open DevOps와 작동하는 방법

DevOps 뉴스레터 신청

Thank you for signing up