[GitHub 기초] Branch, checkout - 2

업데이트:

카테고리:

태그:

“[GitHub 기초] Branch, checkout - 1” 과 이어지는 내용을 다룰 것이므로 “[GitHub 기초] Branch, checkout - 1” 를 먼저보고 해당 포스트를 보는 것을 추천한다.

갈라지는 브랜치(Branch)Permalink

지금부터는 진짜 독립된 작업을 하는 브랜치를 만들어 볼 것이다. 우선 HEAD가 master를 가리키는 상황에서 이번에는 ex2.txt 파일을 수정해보자. 다음과 같이 세 번째 줄을 추가하고 스테이징, commit을 진행한다.

image

이제 로그를 확인해 보면 다음과 같을 것이다. —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

다음은 이를 보기 쉽게 그린 그림이다.

image

이와 같은 방법으로 여러 갈래의 작업을 독립적으로 진해할 수 있다.

브랜치 합병 (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 하지 못한다.

다음의 예시를 한번 따라해보자 우선 새로운 파일을 하나 생성하고 스테이징한 뒤 커밋을 새로 만들어 보자. 이 커밋은 앞으로 진행될 갈라지는 브랜치의 공통된 조상 커밋이 될 것이다.

image

exp1 브랜치를 생성한 뒤 해당 파일의 첫 번째 줄을 수정하고 커밋한다.

checkout -b 를 이용해 생성과 이동을 동시에 할 수 있다.

$ git checkout -b exp1

exp1브랜치에서는 첫 번째 줄을 ‘exp1’이라 수정할 것이고 master 브랜치에서는 첫 번째 줄을 ‘master’이라 수정할 것이다.

image

image

이제 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