git branch와 git merge

2021-07-20 hit count image

Git을 사용하여 버전을 관리할 때 브랜치를 만들고 병합(Merge)하는 방법에 대해서 알아봅시다.

개요

Git으로 소스 코드의 버전 관리를 할 때, 보통 main 브랜치는 최종 버전의 소스 코드(실 서비스에 배포된 소스 코드)를 관리하게 됩니다. 그리고, main 브랜치가 아닌 브랜치를 생성하고 새로운 기능을 개발한 후, 개발이 완료되면, main 브랜치에 병합(Merge)하게 됩니다.

이번 블로그 포스트에서는 git branchgit merge를 사용하여 브랜치를 생성하고 병합하는 방법에 대해서 알아보고, git loggit diff를 통해 브랜치간 차이점을 확인하는 방법에 대해서 알아봅시다.

브랜치 확인

다음 명령어를 사용하면 현재 로컬(Wroking directory)에 존재하는 브랜치를 확인할 수 있습니다.

git branch

git branch 명령어를 실행하며 다음과 같이 로컬에 존재하는 브랜치 리스트가 나오며 *는 현재 선택된 브랜치(checkout된 브랜치)를 의미합니다.

* main
(END)

브랜치 생성

다음 명령어를 사용하면 새로운 브랜치를 생성할 수 있습니다.

git branch BRANCH_NAME

이렇게 새롭게 생성한 브랜치를 선택하기 위해서는 다음과 같이 git checkout을 사용해야 합니다.

git checkout BRANCH_NAME

다음 명령어를 사용하면, 새로운 브랜치를 생성함과 동시에 해당 브랜치를 선택할 수 있습니다.

git checkout -b BRANCH_NAME

브랜치 이력 및 차이점 확인

Git에서는 새로운 브랜치를 만들고, 수정한 후, 브랜치의 이력을 확인하거나, 브랜치간의 차이점을 비교할 수 있습니다.

git log

다음 명령어를 사용하면, 현재 브랜치의 수정 사항을 확인할 수 있습니다.

git log

다음과 같이 현재 브랜치의 수정 내역이 출력됩니다.

commit 18be2fdd7c312cb834610baff4b9388b9d719dce (HEAD -> develop)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:53:13 2021 +0900

    Modify example file

commit da360f74c8227716fa6f005808480bef8811c6b8
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:52:07 2021 +0900

    Add a file

여기에 --branches 옵션을 사용하면, 로컬에 존재하는 모든 브랜치의 이력을 확인할 수 있습니다.

git log --branches

다음과 같이 모든 브랜치의 수정 내용이 출력됩니다.

commit 8c591d99fd58229d6b600a2e9560b21b8e2181be (main)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:55:42 2021 +0900

    Add a new file

commit 18be2fdd7c312cb834610baff4b9388b9d719dce (HEAD -> develop)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:53:13 2021 +0900

    Modify example file

commit da360f74c8227716fa6f005808480bef8811c6b8
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:52:07 2021 +0900

    Add a file

다음과 같이 --graph 옵션을 사용하면, 조금 더 이해하기 쉽게 출력됩니다.

git log --branches --graph

다음과 같이 그래프 형태로 출력됩니다.

* commit 8c591d99fd58229d6b600a2e9560b21b8e2181be (main)
| Author: dev-yakuza <[email protected]>
| Date:   Sat Jul 17 19:55:42 2021 +0900
|
|     Add a new file
|
| * commit 18be2fdd7c312cb834610baff4b9388b9d719dce (HEAD -> develop)
|/  Author: dev-yakuza <[email protected]>
|   Date:   Sat Jul 17 19:53:13 2021 +0900
|
|       Modify example file
|
* commit da360f74c8227716fa6f005808480bef8811c6b8
  Author: dev-yakuza <[email protected]>
  Date:   Sat Jul 17 19:52:07 2021 +0900

      Add a file

마지막으로 --oneline 옵션을 사용하면, 간단하게 브랜치와 메시지만을 확인할 수 있습니다.

git log --branches --graph --oneline

다음과 같이 간단하게 브랜치와 메시지를 확인할 수 있습니다.

* 8c591d9 (main) Add a new file
| * 18be2fd (HEAD -> develop) Modify example file
|/
* da360f7 Add a file

git log 브랜치 비교

다음 명령어를 실행하면, 현재 브랜치와 main 브랜치의 커밋 차이를 확인할 수 있습니다.

git log main..BRANCH_NAME

다음과 같이 main와 특정 브랜치 사이의 차이점을 출력합니다.

commit 8c591d99fd58229d6b600a2e9560b21b8e2181be (main)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:55:42 2021 +0900

    Add a new file

commit 18be2fdd7c312cb834610baff4b9388b9d719dce (HEAD -> develop)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:53:13 2021 +0900

    Modify example file

다음과 같이 -p 옵션을 사용하면, 수정된 내용도 함께 확인할 수 있습니다.

git log -p main..BRANCH_NAME

다음과 같이 수정된 내용을 확인할 수 있습니다.

commit 18be2fdd7c312cb834610baff4b9388b9d719dce (HEAD -> develop)
Author: dev-yakuza <[email protected]>
Date:   Sat Jul 17 19:53:13 2021 +0900

    Modify example file

diff --git a/example.txt b/example.txt
index d00491f..1191247 100644
--- a/example.txt
+++ b/example.txt
@@ -1 +1,2 @@
 1
+2

git diff 브랜치 비교

git diff 명령어를 사용하면 좀 더 간단하게 두 브랜치 사이의 차이점을 확인할 수 있습니다.

git diff main..BRANCH_NAME

다음과 같이 파일명과 수정 내용을 확인할 수 있습니다.

diff --git a/example b/example
deleted file mode 100644
index d00491f..0000000
--- a/example
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/example.txt b/example.txt
index d00491f..1191247 100644
--- a/example.txt
+++ b/example.txt
@@ -1 +1,2 @@
 1
+2
diff --git a/example2.txt b/example2.txt
deleted file mode 100644
index e69de29..0000000

git merge

새로운 브랜치를 만들어, 새로운 기능을 개발하고 완성하였다면, 해당 기능을 main 브랜치(실 서버용 브랜치)에 병합(Merge)하여 새로운 기능을 사용자에게 제공해야 합니다.

그럼 새롭게 개발한 기능을 포함하고 있는 BRANCH_NAMEmain 브랜치에 병합하는 방법에 대해서 알아봅시다. BRANCH_NAMEmain 브랜치에 병합하기 위해서는 우선 main 브랜치로 이동할 필요가 있습니다.

git checkout main

그런 다음, git merg 명령어를 사용하여 main 브랜치에 병합하고자 하는 브랜치를 병합합니다.

git merge BRANCH_NAME

브랜치가 무사히 병합되면 다음과 같은 메시지를 확인할 수 있습니다.

Merge made by the 'recursive' strategy.
 example.txt | 1 +
 1 file changed, 1 insertion(+)

마지막으로, 다음 명령어를 사용하여 병합된 브랜치를 제거합니다.

git branch -d BRANCH_NAME

여기서 사용한 -d 옵션은 병합된 브랜치를 지울 때 사용합니다. 만약, 병합되지 않은 브랜치를 제거하고자 한다면 -D 옵션을 사용해야 합니다.

git branch -D BRANCH_NAME

충돌(Conflict)

git merge 명령어를 사용하여, 브랜치를 병합할 때, 동일한 파일을 수정한 경우 다음과 같이 충돌(Conflict)로 인해 병합에 실패하는 것을 확인할 수 있습니다.

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

git status 명령어를 실행하여, 현재 상태를 확인하면 다음과 같이 병합을 하지 못한 파일을 확인할 수 있습니다.

On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
  both modified:   example2.txt

no changes added to commit (use "git add" and/or "git commit -a")

해당 파일을 열어보면 다음과 같이, 두 브랜치의 충돌 내용이 <<<<<<< HEAD=======, 그리고 >>>>>>> develop으로 구분되어 표시되고 있는 것을 확인할 수 있습니다.

# vi example2.txt
<<<<<<< HEAD
main
=======
develop
>>>>>>> develop

HEAD는 현재 브랜치, 즉 git merge 명령어를 실행한 브랜치(main)입니다. >>>>>>> developgit merge 명령어의 대상이 되는 브랜치(git merge BRANCH_NAME에서 BRANCH_NAME)입니다.

우리는 두 내용을 확인하고, 필요한 내용만을 남기거나 수정해야 합니다. 여기서는 HEAD의 내용만 남기도록 수정하였습니다.

main

이렇게 수정을 완료하였다면, 다음 명령어를 실행하여, 충돌을 수정한 내용을 커밋합니다.

git commit

다음과 같이 자동으로 생성된 커밋 메시지 내용을 확인할 수 있습니다.

Merge branch 'develop' into main

# Conflicts:
#       example2.txt
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#       .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# All conflicts fixed but you are still merging.

이제 :wq로 커밋 메시지를 저장하면 잘 병합되는 것을 확인할 수 있습니다.

완료

이것으로 Git에서 새로운 브랜치를 생성하고, 새로운 브랜치에서 수정한 내용을 병합하는 방법에 대해서 살펴보았습니다. 여러분도 이제 다양한 브랜치 전략을 사용하여, 소스 코드의 버전 관리를 수행해 보시기 바랍니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

책 홍보

스무디 한 잔 마시며 끝내는 React Native 책을 출판한지 벌써 2년이 다되었네요.
이번에도 좋은 기회가 있어서 스무디 한 잔 마시며 끝내는 리액트 + TDD 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
Posts