GDSC Sookmyung 활동/Speaker Session & Hands on Workshop

[Git/GitHub] 2. branch

siraegi 2021. 2. 23. 11:30

이전 포스팅에서 기본적인 commit을 하는 방법에 대해 알아보았습니다. 이번 포스팅에서는 branch 를 활용하는 기본적인 방법에 대해 알아보겠습니다.

 

먼저 branch의 개념을 간략하게 말하자면, 한 저장소에서 다른 개발자들과 작업하고 싶을 때 브랜치를 만들어 작업합니다.

 

  1.  내가 혼자 한 줄로 쌓아가던 커밋을 여러 줄로 쌓아갈 수 있도록 하는 것입니다. 이 때 한 줄이 한 브랜치입니다.
  2.  여러 명이 작업하다보면 같은 부분의 코드를 수정할 가능성이 있습니다. 그러면 나중에 충돌이 일어납니다.
  3.  여러 줄로 커밋을 쌓고 나중에 합치면서 충돌을 해결해서 하나의 완성된 코드로 만들어 갑니다.

자, 이제 위의 리스트를 차례로 수행해보겠습니다. 여기서는 간단하게 하기 위해 여러 사람과 함께 작업하는 저장소 대신 이전 포스팅에서 만든 혼자 쓰는 저장소에서 해보겠습니다.

※ practice-git 저장소에서 실습합니다.

practice-git/
 ㄴpractice.txt
 ㄴREADME.md

[practice.txt]

git practice 1

 

이전 포스팅처럼 cmd (윈도우는 Git Bash, 맥OS는 terminal) 에서 진행합니다.

 

 

 

1.  커밋을 여러 줄로 쌓아가기 - branch 만들고 이동하기

git branch 브랜치명

커밋을 여러 줄의 branch 를 따서 따로 쌓아가기 위해 branch를 생성해봅니다. 현재 위치하고 있는 base 브랜치(master)에서 분기하는 브랜치를 새로 만듭니다. 여기서는 test라는 이름의 브랜치를 만들어보겠습니다.

$ git branch test
git branch

git branch 명령어는 현재 내가 위치해있는 브랜치가 어디인지를 보여줍니다.

$ git branch
* main
  test

여기 보시면, main, test 브랜치 두 가지의 갈래 중 현재는 main 브랜치에 있는 것을 볼 수 있습니다. 지금까지 우리가 커밋을 하고 있었던 기본 브랜치는 main 이었던 것입니다.

git checkout 브랜치명

git checkout 명령어를 이용하면 해당 브랜치로 위치를 옮겨갈 수 있습니다.

$ git checkout test
Switched to branch 'test'

$ git branch
  main
* test

git branch 명령어로 현재 위치를 확인해보면 잘 이동했음을 볼 수 있습니다.

이동 후에는 저장소가 아래와 같이 main 브랜치와 똑같은 상태입니다. 왜냐하면 main 브랜치에서 그대로 복사한 것처럼 브랜치를 따온 것이기 때문입니다.

practice-git/
 ㄴpractice.txt
 ㄴREADME.md

 

 

2. 여러 명이서 같은 부분의 코드 수정하기 - 여러 branch에서 변경사항 커밋하기

[practice.txt]

git practice 1

 

practice.txt 파일을 test 브랜치에서 아래와 같이 수정하고 커밋해봅시다.

 

[practice.txt]

GIT PRACTICE 1

 

이전 포스팅에서 배운 것처럼 변경사항을 커밋을 해봅니다. (git commit -am "커밋메시지"  add 와 commit을 동시에 하는  명령어)

$ git status
On branch test
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   practice.txt

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

$ git commit -am "first commit in test branch"
warning: LF will be replaced by CRLF in practice.txt.
The file will have its original line endings in your working directory
[test 19534f2] first commit in test branch
 1 file changed, 1 insertion(+), 1 deletion(-)

git checkout 명령어로 main 브랜치로 이동 후, 아래와 같이 파일을 수정하고 변경사항을 커밋해봅니다.

[practice.txt]

git practice 2

$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

$ vi practice.txt

$ git commit -am "second commit"
[main 6f93904] second commit
 1 file changed, 1 insertion(+), 1 deletion(-)

 

 

3. 여러 줄에서 쌓아온 변경사항 합치며 충돌 해결하기 - branch 병합 (merge)

main, test 브랜치 각각에서 파일이 수정되어 이대로 두 버전의 파일을 합치면 conflict가 납니다. 이때 합치는 과정을 merge(병합)이라고 합니다.

다른 파일의 다른 부분을 수정했다면 합치기 쉬우니 Git 이 알아서 잘 merge 해줍니다. 하지만, 같은 파일의 같은 부분 코드를 수정하면 Git은 어떻게 병합해야 할지 몰라 conflict를 띄우고 유저에게 merge를 떠넘깁니다. 이때는 수동으로 코드를 한 줄씩 살펴보며, 어느 코드를 채택하고 어떻게 합칠 지 타이핑하며 직접 수정해야 합니다.

git merge 브랜치명

git merge 명령어로 병합할 때는 main 브랜치 기준으로 병합하려면 master 브랜치에 위치한 상태로 해야 합니다.

즉, main 브랜치에 test 브랜치를 병합하는 것입니다.

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

Auto-merging이 CONFLICT 났다고 합니다. 자동 병합이 실패했으니 네가 conflict를 해결하고 결과를 커밋해라!

이럴 땐, 그냥 파일 열어서 수동으로 고쳐야 합니다. 파일을 열어보면..

<<<<<<< HEAD
git practice 2
=======
GIT PRACTICE 1
>>>>>>> test

<<<<<< HEAD 부터 ====== 까지 HEAD가 위치한 브랜치(현재 위치한 main 브랜치)의 최신 상태이고,

======부터 >>>>>> 까지 test 브랜치의 최신 상태입니다. 

잘 비교해가며 어떤 것을 최종적으로 main 브랜치에 반영할 지 결정해서 파일을 수정합니다.

저는 아래와 같이 수정해보았습니다.

[practice.txt]

GIT PRACTICE 2

$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

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:   practice.txt

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

$ git commit -am "merge main & test"
[main ca1ae3c] merge main & test

그리고 merge 했다는 커밋을 해줍니다. 이제 두 브랜치의 병합이 끝났습니다.


추가로, GitHub 에 방금 완료한 커밋들을 push해서 올린 후, 저장소의 Insights-Network 에 가보면 이렇게 브랜치의 커밋과 병합 과정을 그래프로 쉽게 볼 수 있습니다.