HOWTO · Git

Git에서 분기를 마스터로 병합

Git 병합은 개발자가 다른 기능 분기를 프로덕션 분기에 결합할 수 있는 훌륭한 기능입니다. 이 튜토리얼은 기능 분기를 마스터와 병합하는 다양한 전략을 보여줍니다. 또한 병합 및 리베이스의 의미 체계도 탐색하므로 개발자는 다른 것과 비교하여 가장 좋은 것을 선택합니다.

이 페이지의 내용

git의 가장 강력한 기능 중 하나는 브랜치 생성 및 병합 작업입니다. Git을 사용하면 사용자가 새 분기를 만들고 이를 개발 코드에 병합할 수 있습니다. 이 기능은 보다 구체적이고 작고 세분화된 작업을 장려하여 여러 프로젝트의 개발 프로세스 워크플로를 개선합니다.

이 튜토리얼 기사에서는 git 기능 분기를 마스터로 병합하는 다양한 접근 방식에 대해 설명합니다.

git의 주요 장점은 분기 시스템입니다. GIT의 모든 마법은 바로 이 지점에 있습니다! 마스터 브랜치는 모든 수정 사항을 전달합니다. 따라서 이 브랜치에 직접 수정을 가하는 것이 아니라 다른 브랜치에 수정을 가하고 다양한 테스트를 거쳐 마스터 브랜치에 통합하는 것이 목표입니다.

단순화를 위한 튜토리얼에서 master 브랜치와 feature-1로 알려진 기능 브랜치의 두 가지가 있다고 가정해 보겠습니다. 메인 브랜치는 프로덕션 코드를 포함하는 마스터 브랜치이고, 두 번째 브랜치는 수정이 실행되거나 새로운 기능이 구현되는 곳입니다. 결국 기능이나 버그가 승인되면 마스터로 병합됩니다.

초기_리포지토리

실제 예를 들어 두 분기 병합의 데모를 시작하겠습니다. 시작하려면 다음이 필요합니다.

전제 조건

GitHub에 리포지토리 생성

Github에 소개된 대로 초기 저장소를 만들 수 있습니다.

그런 다음 저장소 페이지의 파일 추가 버튼을 사용하여 마스터 분기에 두 개의 파일을 추가합니다. 파일 이름은 다음과 같습니다.

  • file1.txt
  • file2.txt

이 예에서는 다음 텍스트 콘텐츠가 각각 file1.txt 및 파일 file2.txt에 추가됩니다.

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

클론 리포지토리

그런 다음 GitHub에서 새로 생성된 리포지토리를 시스템으로 복제하여 코드의 로컬 복사본을 생성합니다. 클론 URL은 아래와 같이 코드 버튼에서 검색할 수 있습니다.

클론_리포지토리

다음 명령을 사용하여 복제합니다.

$ git clone git@github.com:project/demorepo.git

성공적으로 복제되면 다음 명령을 사용하여 마스터 분기 파일의 내용을 표시하고 확인합니다.

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

기능 분기 만들기

$ git branch feature-1

이 명령은 새 분기를 만들고 git에 새 커밋을 만들지 않습니다.

체크아웃 기능 분기

이전에는 git branch feature-1을 사용하여 새 분기를 만들었습니다. 그러나 활성 분기는 master 분기입니다. 새 분기를 활성화하려면 터미널에서 다음 명령을 사용하십시오.

$ git checkout feature-1
Switched to branch 'feature-1'

위의 명령은 활성 브랜치를 master에서 feature-1로 전환합니다. 이제 이 분기는 개별 개발을 위한 준비가 되었습니다.

기능 분기에서 파일 수정

몇 가지 커밋을 추가하거나 feature-1 분기에 새 줄을 추가합니다. 이 경우 file2.txt는 로컬에서 수정되고 나중에 마스터 분기로 다시 병합됩니다.

지금까지의 변경 사항에 대해 커밋 다이어그램은 다음과 같습니다. A와 E는 모두 master 및 feature-1 분기 상태를 나타냅니다. 현재 커밋 A와 E는 체크아웃 중에 파일이 변경되지 않는 것과 동일합니다.

A  ← master
   \
     E  ← feature-1

이제 file1.txt가 새 텍스트로 업데이트됩니다. 이 명령을 사용하여 콘텐츠를 업데이트합니다.

$ echo "file update in feature branch" > file1.txt

이제 file2.txt에는 아래와 같은 내용이 있습니다.

$ cat file2.txt
This is dummy test in 2nd file

file1.txt의 이전 내용과 새 내용의 차이점은 아래 명령을 사용하여 확인할 수 있습니다.

$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch

이제 이 파일을 준비하고 아래 명령을 통해 로컬 커밋을 만듭니다.

$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
 1 file changed, 1 insertion(+), 2 d

커밋 트리의 현재 스냅샷은 다음과 같습니다. 여기 F는 이전 단계에서 생성된 새 커밋입니다.

A  ← master
  \
    E --- F ← feature-1

실제 예를 보여주기 위해 원격 master도 다른 개발자에 의해 동시에 변경되며 이러한 변경 사항은 C 커밋 및 D 커밋으로 마스터에 푸시됩니다.

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

아래는 마스터 브랜치의 Github 저장소에 있는 file1.txt의 업데이트된 내용입니다. 알림 2행이 업데이트되고 3행과 4행이 새로 생성됩니다.

파일1_콘텐츠

아래 명령을 사용하여 실시간으로 명령 셸에서 분기 기록을 시각화하여 로컬에서 유효성을 검사할 수도 있습니다.

$ git fetch
$ git log --all --decorate --oneline --graph

커밋_그래프

Git에서 병합 준비

Git을 사용하면 기능 분기 변경 사항을 원격 master 분기와 병합할 수 있는 두 가지 가능성이 있습니다.

  1. merge 방법
    Git merge는 변경 사항을 다른 분기에 커밋하는 명령입니다. 이를 통해 개발자는 기능 분기에서 독립적인 코드 줄을 가져와 git merge 도구를 통해 마스터의 단일 분기에 통합할 수 있습니다.

  2. rebase 방법
    Git rebase는 매우 다르게 수행된다는 점을 제외하고는 본질적으로 동일한 목적으로 사용되는 또 다른 명령입니다.

두 가지 방법을 자세히 이해합시다.

Git의 merge 메소드를 사용하여 분기를 마스터에 병합

merge는 feature 및 master 분기를 관련된 모든 분기의 내용을 유지하는 커밋으로 통합하는 것을 목표로 합니다. Git은 이를 병합 커밋이라고 합니다. 이것은 또한 merge가 여러 분기를 조작한다는 것을 의미합니다.

가지가 갈라지면, 즉 하나가 다른 것의 조상이 아닙니다. Git은 여러 부모가 있는 새로운 추가 커밋을 만들어 병합을 달성할 수 있습니다. 다음 그림에서 다른 브랜치에 D 커밋과 F 커밋이 있고 브랜치를 혼합하면( git merge를 통해) 결과는 부모가 B와 E인 커밋 G입니다.

A --- B --- C --- D ---	
  \				         \  
    \					  G  ← master
      E --- F --------- /	

위의 다이어그램에서 G는 새로 생성된 커밋이며 전적으로 git에 의해 생성됩니다. 이 커밋에는 두 명의 부모가 있습니다! 그리고 그들은 주문이 있습니다:

  • 첫 번째 부모는 이전에 master였던 D입니다.
  • 두 번째 부모는 이전에 feature-1이었던 F입니다.

이러한 유형의 커밋을 병합 커밋이라고 합니다.

이제 저장소 예제로 다시 전환하고 새로 생성된 feature-1 브랜치를 master에 병합합니다.

먼저 마스터 브랜치를 확인하십시오.

$ git checkout master

이제 원격 마스터 변경 사항을 로컬 master로 가져옵니다.

$ git pull origin master

From github.com:repo/demorepo

 * branch            master     -> FETCH_HEAD
   Updating 17cc6b4..a802b6b
   Fast-forward
    file1.txt | 5 ++++-
    1 file changed, 4 insertions(+), 1 deletion(-)

그런 다음 아래 명령을 사용하여 기능 분기, 즉 feature-1을 현재 활성 분기에 병합합니다.

$ git merge feature-1

이 단계가 성공적으로 완료되면 feature-1 분기가 master 분기와 완전히 병합됩니다. 그러나 git이 이러한 병합 충돌을 자동으로 해결할 수 없으면 병합 충돌 오류와 함께 실패합니다.

이것은 매우 일반적인 시나리오입니다. 두 분기가 파일의 동일한 부분을 수정하고 git이 사용할 부분을 확인할 수 없는 경우에 발생할 수 있습니다. 그것은 바로 우리의 예에서 일어나는 일입니다. 이 경우는 git을 통해 아래에 표시됩니다.

Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

git은 충돌이 발생할 때마다 <<<<<<< & =======를 추가하여 충돌을 일으킨 섹션을 강조 표시하며 이는 수동으로 해결해야 합니다.

File1_MergeConflict

파일의 최종 마스터 버전에서 유지할 부분이 결정되면 개인은 관련 없는 코드(충돌 표시기 포함)를 제거해야 합니다. 결국 아래와 같이 원격 브랜치에 변경 사항을 푸시합니다.

$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push

이렇게 하면 feature-1 분기가 원격 master에 성공적으로 병합됩니다.

다음으로 아래 명령어로 다시 분기 기록을 확인합니다.

git log --all --decorate --oneline --graph

병합_그래프

git merge 가 feature-1 브랜치를 origin/master 와 병합하기 위해 commit-id가 1acce69인 Merge Commit을 생성했는지 확인할 수 있습니다.

rebase 메소드를 사용하여 분기를 마스터로 병합

다시 한 번 기능 및 마스터 분기가 동기화되지 않아 병합해야 하는 상황을 고려하십시오. 이전에 이 상황을 보여 주는 그림도 생각해 보겠습니다.

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

병합하는 다른 방법으로 rebase 옵션을 사용하여 feature-1 분기를 master 분기에 병합할 수 있습니다. rebase는 기능 브랜치의 커밋을 마스터 브랜치 앞에 배치하여 관련된 브랜치를 통합합니다.

이것은 아래 명령을 통해 달성됩니다.

git checkout master
git pull
git checkout feature-1
git rebase master

rebase를 실행하면 아래와 같은 그림을 볼 수 있습니다.

A --- B --- C --- D----(operation rebase)----- E--------F   ← master

위의 그림에서 rebase가 하는 일은 선형적이고 깨끗하며 읽기 쉬운 커밋 기록을 생성한다는 것을 알 수 있습니다. 병합하면 이상한 병합 커밋이 추가로 생성되지 않습니다.

이 접근 방식의 단점은 rebase가 이러한 분기의 커밋 기록 재작성을 포함하여 관련된 분기의 전체 구조를 변경한다는 것입니다. rebase는 merge commit을 생성하지 않기 때문에 rebase가 프로세스 마지막에 선형 분기를 생성하기 때문에 두 분기가 병합된 시점에 대한 추적성을 얻을 수 없습니다.

결론

두 명령 모두 매우 유용합니다. 그러나 상황에 따라 각 측에 다음과 같은 장점이 있습니다.

Git rebase

  • 복잡한 역사를 간소화합니다.
  • 바쁜 브랜치가 있는 리포지토리에서 커밋 노이즈를 병합하지 마십시오.
  • 이력이 보존되지 않아 제대로 사용하지 않으면 위험합니다.

Git merge

  • 사용이 간편합니다.
  • 매번 추가 병합 커밋이 생성되기 때문에 커밋 히스토리가 혼란스럽고 지저분해 보입니다.
  • 완전한 역사와 연대순을 보존합니다.