Codesigner

[Git] Git Branching - Merge conflict & Review 본문

Git /git

[Git] Git Branching - Merge conflict & Review

eunsukimme 2019. 4. 9. 17:05

이전 포스팅에서 mastersamsung 브랜치가 깔끔하게 merge 되었다. samsung 브랜치에서 커밋 한 이후 master에서 merge 하기 전에 아무런 작업을 하지 않았기 때문이다. 그래서 Git 은 간단히 master를 업데이트시킬 수 있었고, 이를 'Fast-forward'라고 한다고 배웠다. 그런데, 만약 master 에서 merge 하기 전에 커밋을 생성한다면 어떻게 될까? 더 나아가, master 에서도 samsung 브랜치에서 작업한 것과 동일한 작업을 한다면? 이러한 상황에서 merge 하게 되면, Git은 당신이 어떤 변경사항을 받아들이고자 하는지 몰라서 conflict를 발생시킨다. 이를 merge conflict라고 한다. 

 

 

 

merge conflict I

 

이전 포스팅을 잘 따라 왔다면 현재 master branch에 위치하고 있을 것이다. resume.txt를 다음과 같이 수정한 후 커밋해보자

C:\Users\glafu\Desktop\git_test>vim resume.txt

C:\Users\glafu\Desktop\git_test>cat resume.txt
i want to be a programmer!
i want to work at samsung!
skills: c++, python, javascript

C:\Users\glafu\Desktop\git_test>git add resume.txt

C:\Users\glafu\Desktop\git_test>git commit -m "Add new line of skills on master"
[master 685f61d] Add new line of skills on master
 1 file changed, 1 insertion(+)

C:\Users\glafu\Desktop\git_test>

그런 다음, samsung 브랜치로 이동하여 resume.txt를 다음과 같이 수정한 후 커밋해보자

C:\Users\glafu\Desktop\git_test>git checkout samsung
Switched to branch 'samsung'
M       hello.txt

C:\Users\glafu\Desktop\git_test>vim resume.txt

C:\Users\glafu\Desktop\git_test>cat resume.txt
i want to be a programmer!
i want to work at samsung!
skills: java, solidity, typescript

C:\Users\glafu\Desktop\git_test>git add resume.txt

C:\Users\glafu\Desktop\git_test>git commit -m "Add new line of skills on samsung"
[samsung c23d146] Add new line of skills on samsung
 1 file changed, 1 insertion(+)

C:\Users\glafu\Desktop\git_test>

지금 우리가 한 작업은 merge conflict를 인위적으로 발생시키기 위한 것이다. 현재 상황을 정리하면, master 브랜치에서와 samsung 브랜치에서 똑같은 파일을 두고 서로 다르게 수정한 상황이다. 

 

 

 

merge conflict II

 

자, 이제 master 브랜치로 돌아와서 samsung 브랜치를 merge 할건데, 문제가 발생할 것이라고 예상할 수 있겠는가? 똑같은 파일을 두고 각 브랜치에서 서로 다르게 수정한 걸 합치려면, 어느 브랜치의 변경사항을 적용해야 하는지 결정해야 할 것이다. Git은 우리에게 그걸 결정하라고 merge conflict를 발생시키는 것이다. 우선 git checkout 명령으로 master로 돌아가자

C:\Users\glafu\Desktop\git_test>git checkout master
Switched to branch 'master'
M       hello.txt

C:\Users\glafu\Desktop\git_test>

그런 다음, samsung 브랜치를 merge 해보자

C:\Users\glafu\Desktop\git_test>git merge samsung
Auto-merging resume.txt
CONFLICT (content): Merge conflict in resume.txt
Automatic merge failed; fix conflicts and then commit the result.

C:\Users\glafu\Desktop\git_test>

역시나 merge conflict 가 발생한 걸 확인할 수 있다. 문제를 해결하기 위해 resume.txt를 열어서 내용을 보면 다음과 같다. 

i want to be a programmer!
i want to work at samsung!
<<<<<<< HEAD
skills: c++, python, javascript
=======
skills: java, solidity, typescript
>>>>>>> samsung

못 보던 marking 들을 볼 수 있는데, 이건 Git이 남긴 것이다. resume.txt의 HEAD(master) 버전과 samsung 버전의 차이를 보여주고 있는 것이다. 우리가 해야 할 일은 HEAD 버전을 선택할 것인지, samsung 버전을 선택할 것인지 결정하는 것이다. 우리는 samsung 버전을 결정했다고 가정하자. 그러면 master 브랜치에서 작성한 라인을 지워주면 된다. 주의할것은, Git 이 남긴 모든 marking 들도 함께 지워줘야 한다는 것이다! "HEAD", "samsung", "<<<<<<" 그리고 "======" 들 까지 모두 지워줘야 한다. 그러면 최종적으로 resume.txt의 모습은 다음과 같다

i want to be a programmer!
i want to work at samsung!
skills: java, solidity, typescript

이제 수정한 resume.txt 를 다시 커밋하도록 하자. 이때, 커밋 메시지를 "Resolve merge conflict"라고 하여 커밋의 목적성을 분명하게 하자

C:\Users\glafu\Desktop\git_test>git add resume.txt

C:\Users\glafu\Desktop\git_test>git commit -m "Resolve merge conflict"
[master 90c725c] Resolve merge conflict

C:\Users\glafu\Desktop\git_test>

이로써 merge conflict 가 해결되었고, 정상적으로 merge 되었다

 

 

 

delete branch

 

Git에서 branch를 만드는 목적은 master에 병합하기 위함이다. Branch에서 필요한 작업을 수행하고, 목적을 달성하게 되면, 즉 master에 merge 하고 나면 제 역할을 다한 것이므로 브랜치를 지울 수 있다. 명령은 다음과 같다

git branch -d branch_name

위 명령은 주어진 브랜치의 이름에 해당하는 브랜치를 Git 프로젝트에서 삭제한다. 우리의 경우 samsung 브랜치의 모든 내용을 master 에 merge 하였으므로, samsung 브랜치를 지워보도록 하자

C:\Users\glafu\Desktop\git_test>git branch -d samsung
Deleted branch samsung (was c23d146).

C:\Users\glafu\Desktop\git_test>

브랜치가 지워졌다고 나오는데, 실제로 지워졌는지 git branch 명령으로 확인해보자

C:\Users\glafu\Desktop\git_test>git branch
* master

C:\Users\glafu\Desktop\git_test>

존재하는 브랜치가 master 뿐임을 알 수 있다. samsung 브랜치가 성공적으로 지워졌다

 

 

 

generalizations

 

지금까지 branch에 대해서 많은 것들을 배웠는데, 핵심 내용과 커맨드들을 정리해 보는 시간을 가져보자

  • Git branch는 프로젝트상에서 브랜치를 나눔으로써 서로 간에 영향을 주지 않고 실험적으로 프로젝트의 여러 기능이나 버전을 관리할 수 있게 해 준다

다음 명령들은 Git에서 브랜치를 활용하는 커맨드들이다

  • git branch - 프로젝트의 모든 브랜치를 나열한다

  • git branch branch_name - 주어진 이름으로 새로운 브랜치를 생성한다

  • git checkout branch_name - 주어진 이름의 브랜치로 이동한다

  • git merge branch_name - 파일의 변화들을 giver 브랜치에서 reciever 브랜치에 적용시킨다

  • git branch -d branch_name - 주어진 이름의 브랜치를 삭제한다

 

 

지금까지 Git에서 branch가 무엇이고 이를 활용한 workflow 및 merge conflict와 해결방법 그리고 몇 가지 커맨드에 대해서 알아보았다. 현재까지 이 시리즈에서의 모든 작업은 사용자 한 명(필자)에게서 이뤄지고 있는데, 다음 포스팅에서는 Git이 제공하는 강력한 장점 중 하나인 협업(teamwork) 기능에 대해서 알아보도록 하자. 

 

 

 

 

'Git > git' 카테고리의 다른 글

[Git] Git Teamwork - Workflow & Generalizations  (0) 2019.04.09
[Git] Git Teamwork - Remote Repository  (0) 2019.04.09
[Git] Git Branching - fast forward  (1) 2019.04.09
[Git] Git Backtracking - checkout & reset  (0) 2019.04.09
[Git] Basic Git Workflow  (0) 2019.04.08
Comments