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

Sharad Dixit 2023년1월30일
  1. 전제 조건
  2. Git에서 병합 준비
  3. Git의 merge 메소드를 사용하여 분기를 마스터에 병합
  4. rebase 메소드를 사용하여 분기를 마스터로 병합
  5. 결론
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는 모두 masterfeature-1 분기 상태를 나타냅니다. 현재 커밋 AE는 체크아웃 중에 파일이 변경되지 않는 것과 동일합니다.

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 메소드를 사용하여 분기를 마스터에 병합

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

가지가 갈라지면, 즉 하나가 다른 것의 조상이 아닙니다. Git은 여러 부모가 있는 새로운 추가 커밋을 만들어 병합을 달성할 수 있습니다. 다음 그림에서 다른 브랜치에 D 커밋과 F 커밋이 있고 브랜치를 혼합하면( git merge를 통해) 결과는 부모가 BE인 커밋 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 mergefeature-1 브랜치를 origin/master 와 병합하기 위해 commit-id가 1acce69Merge 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가 이러한 분기의 커밋 기록 재작성을 포함하여 관련된 분기의 전체 구조를 변경한다는 것입니다. rebasemerge commit을 생성하지 않기 때문에 rebase가 프로세스 마지막에 선형 분기를 생성하기 때문에 두 분기가 병합된 시점에 대한 추적성을 얻을 수 없습니다.

결론

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

Git rebase

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

Git merge

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

관련 문장 - Git Merge