[GitHub 기초] Branch, checkout - 2
카테고리: GitHub
태그: Git
“[GitHub 기초] Branch, checkout - 1” 과 이어지는 내용을 다룰 것이므로 “[GitHub 기초] Branch, checkout - 1” 를 먼저보고 해당 포스트를 보는 것을 추천한다.
갈라지는 브랜치(Branch)Permalink
지금부터는 진짜 독립된 작업을 하는 브랜치를 만들어 볼 것이다. 우선 HEAD가 master를 가리키는 상황에서 이번에는 ex2.txt 파일을 수정해보자. 다음과 같이 세 번째 줄을 추가하고 스테이징, commit을 진행한다.
이제 로그를 확인해 보면 다음과 같을 것이다. —decorate —graph를 이용해 그래프의 형태로 확인할 수 있다.
$ git log --oneline --decorate --graph --all
* 1c241f4 (HEAD -> master) other change
| * b16d6a4 (testing) checkout test
|/
* e58febc (origin/master) vscode push
* 61f892c second version
* 0f1fcf9 first commit
다음은 이를 보기 쉽게 그린 그림이다.
이와 같은 방법으로 여러 갈래의 작업을 독립적으로 진해할 수 있다.
브랜치 합병 (Merge)Permalink
브랜치를 이용해 여러 갈래로 작업을 하다가 중복되는 브랜치가 존재하거나 혹은 더이상 분리해 작업을 할 필요가 없거나 등의 이유로 여러 브랜치를 하나로 합쳐야할 경우가 생길 것이다. 이때 사용하는 기능이 바로 Merge이다.
우선 Merge를 하기전에 checkout을 이용해 주 가될 즉 합쳐진 브랜치의 이름이될 브랜치로 HEAD를 옮긴다. 일반적으로 하나의 브랜치로 합칠경우 최초의 브랜치인 master브랜치를 많이 사용하므로 본 예제에서도 master브랜치에 다른 브랜치를 합쳐보도록 하겠다.
현재 HEAD가 master 브랜치를 가리키고 있으므로 바로 merge명령어를 이용해 testing 브랜치와 master 브랜치를 합쳐보자.
#$ git merge (합칠 브랜치 이름)
$ git merge testing
기본적으로 merge를 사용할 경우 합칠 브랜치들이 가리키는 커밋과 그 두 브랜치의 공통 조상 커밋을 이용하여 3-way Merge를 진행한다. 그리하여 공통된 변화와 서로 다른 변화점을 비교하여 합치고 그것을 새로운 커밋으로 만들어 이동한다.
로그를 확인해보자.
$ git log --oneline --decorate --graph --all
* 30ebefd (HEAD -> master) Merge branch 'testing'
|\
| * b16d6a4 (testing) checkout test
* | 1c241f4 other change
|/
* e58febc (origin/master) vscode push
* 61f892c second version
* 0f1fcf9 first commit
충돌 (Conflict)Permalink
간혹 위와 같은 3-way Merge가 실패할 경우가 있다. 예를 들어 Merge 하는 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하고 Merge 하면 Git은 해당 부분을 Merge 하지 못한다.
다음의 예시를 한번 따라해보자 우선 새로운 파일을 하나 생성하고 스테이징한 뒤 커밋을 새로 만들어 보자. 이 커밋은 앞으로 진행될 갈라지는 브랜치의 공통된 조상 커밋이 될 것이다.
exp1 브랜치를 생성한 뒤 해당 파일의 첫 번째 줄을 수정하고 커밋한다.
checkout -b 를 이용해 생성과 이동을 동시에 할 수 있다.
$ git checkout -b exp1
exp1브랜치에서는 첫 번째 줄을 ‘exp1’이라 수정할 것이고 master 브랜치에서는 첫 번째 줄을 ‘master’이라 수정할 것이다.
이제 merge명령어를 이용해 Merge를 실행하면 충돌 메시지가 출력될 것이다.
$ git merge exp1
#Auto-merging Conflict.txt
#CONFLICT (content): Merge conflict in Conflict.txt
#Automatic merge failed; fix conflicts and then commit the result.
충돌이 일어난 파일은 unmerged 상태로 표시가 되고 status 명령어를 이용해 충돌이 일어난 파일을 찾을 수 있다.
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(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: Conflict.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git은 충돌이 난 부분을 표준 형식에 따라 표시해준다. 그러면 개발자는 해당 부분을 수동으로 해결한다. 충돌 난 부분은 아래와 같이 표시된다.
<<<<<<< HEAD
master
=======
exp1
>>>>>>> exp1
======= 위쪽의 내용은 HEAD 버전(merge 명령을 실행할 때 작업하던 master 브랜치)의 내용이고 아래쪽은 exp1 브랜치의 내용이다. 충돌을 해결하려면 위쪽이나 아래쪽 내용 중에서 고르거나 새로 작성하여 Merge 한다. 충돌 부분을 적당히 해결했다면 다시 스테이징하여 커밋하는 것으로 Merge를 완료할 수 있다.
근본적인 해결 방안은 아니지만 충돌 상황을 빠져나오기 위해 Merge를 취소하는 방법도 있는데 이를 위한 명령어는 다음과 같다.
$ git merge --abort