오도원입니다.

건강과 행복을 위하여

Development/Git

3장. 깃과 브랜치

오도원공육사 2020. 2. 2. 16:22
반응형

제대로 동작하는 소스는 그대로 둔 채 새 소스를 추가한 버전을 따로 만들어 관리하고, 완벽하게 완성한 다음 원래 소스에 더할 수 있다면 편리할 것이다. 이때 사용하는 방법이 바로 깃의 '브랜치(branch)'라는 기능이다.

 

1. 브랜치란?

2. 브랜치 만들기

3. 브랜치 정보 확인하기

4. 브랜치 병합하기

5. 브랜치 관리하기

 

1. 브랜치란?

1) 브랜치 기능 살펴보기

제품이 출시되고 나면 고객사마다 추가로 요구하는내용이 다른 것이다. 요구사항을 반영하다 보면 고객사에 따라 제품이 달라질 것이다. 

 

branch

새로운 브랜치를 만들면 기존에 저장한 파일을 master브랜치에 그대로 유지하면서 기존 파일 내용을 수정하거나 새로운 기능을 구현할 파일을 만들 수 있다. 이를 분기(branch)한다고 한다.

 

merge

새 브랜치에서 원하는 작업을 끝냈다면 새 브랜치에 있던 파일을 원래 master브랜치에 합칠 수 있다. 이를 병합(merge)한다고 한다.

 

깃으로 버전관리를 시작하면 기본적으로 master라는 브랜치가 만들어진다. 사용자가 커밋할 때마다 master브랜치는 최신 커밋을 가리킨다. 즉, 브랜치는 커밋을 가리키는 포인터라고 생각하면 된다. 

 

2. 브랜치 만들기

manual 디렉터리를 만들고 work.txt 파일을 work 1이라는 내용으로 커밋한다. 이후에 work 2, work 3이라는 메시지로 추가로 커밋한다. 그리고 git log로 확인하면 이런 식으로 나온다.

HEAD는 현재 작업중인 브랜치를 가리키고, master는 브랜치에서 가장 최신 커밋을 가리킨다. 

 

1) 새 브랜치 만들기

깃에서 브랜치를 만들거나 확인하는 명령.

$ git branch

현재 master브랜치만 있다. 새로운 브랜치를 만들려면 git branch 다음에 생성할 브랜치의 이름을 적는다.

$ git branch apple

이제 apple, master 두 개의 브랜치가 있다. *은 현재 작업중인 브랜치를 의미한다. 위와 같은 방법으로 2개의 브랜치를 더 만든다. 

 

2) 브랜치 사이 이동하기 - git switch 

책에서는 checkout으로 나와있지만 Git 2.23.0 버전이후로 checkout이 restore와 swtich로 기능 분리되었다. 

현재 master 브랜치를 비롯해 ms, google, apple 브랜치가 work 3커밋 상태에서 만들어진 것을 확인할 수 있다. work.txt 파일 안에 'master work 4'라는 내용을 추가한 후, master work 4 메시지로 커밋한다.

이제 master 브랜치에 새로운 커밋이 추가되었다. 그러면 커밋로그가 어떻게 바뀌었을까?

현재 브랜치(HEAD)는 master이고, master브랜치의 최신 커밋은 master content 4이다. 그리고 ms, google, apple 브랜치의 최신 커밋은 work 3이다. 

 

브랜치를 이동해보도록 하자.

$ git switch [브랜치 이름]

디렉토리 명 뒤에 있는 (master)가 (apple)로 바뀌었다. 현재 작업 중인 브랜치가 apple이라는 뜻이다.  커밋 로그를 확인해보겠다.

최신 커밋 해시에서 HEAD가 apple을 가리키고 있다. 즉, apple 브랜치의 최신 커밋은 처음 분기될 때 work 3 커밋 그대로이다.

master브랜치에서 입력했던 master content 4가 없다. 이를 통해 apple 브랜치가 master 브랜치에서 분기된 이후에 master 브랜치에 추가된 커밋은 apple 브랜치에 영향을 미치지 않았다는 것을 알 수 있다.

 

3. 브랜치 정보 확인하기

1) 새 브랜치에서 커밋하기

apple 브랜치에서 work.txt에 'apple content 4' 내용을 입력 후 'apple content 4' 메시지로 커밋한다.

(HEAD -> apple) 이라고 되어 있으니 현재 apple 브랜치의 체크아웃한 상태이고, apple 브랜치의 최신 커밋은 'apple content 4'이다.

 

--branches 옵션을 사용하면 각 브랜치의 커밋을 함께 볼 수 있다.

$ git log --oneline --branches

(HEAD -> apple), (master), (ms, google)을 보고 어떤 브랜치에서 만든 커밋인지를 구별할 수 있다.

 

브랜치와 커밋의 관계를 그래프 형태로 쉽게 확인하려면 --graph 옵션을 함께 사용한다. 

apple 브랜치에서는 'work 3' 커밋 다음에 'apple content 4' 커밋이 만들어졌다는 뜻이고, master 브랜치나 apple 브랜치는 'work 3' 커밋까지는 같고 그 이후부터 브랜치마다 다른 커밋을 만들었다는 사실을 알 수 있다. 

 

2) 브랜치 사이의 차이점 알아보기

마침표 왼쪽에 있는 브랜치를 기준으로 오른쪽 브랜치와 비교한다.

git log master..apple

$ git log apple..master

 

4. 브랜치 병합하기

1) 서로 다른 파일 병합하기

새로운 디렉토리를 생성
1 입력 후 커밋

 

$ git branch o2

o2 브랜치 생성

 

master 브랜치에서 master.txt 파일을 하나 더 생성 후, 'master work 2'라는 메시지와 함께 커밋한다.

'master work 2' 커밋은 o2 브랜치에 영향을 미치지 않는다. 이제 o2 브랜치로 switch 한다.

$ git switch o2

o2.txt 파일을 생성 후 커밋한다. 

 

$ git log --oneline --branches --graph

work 1 브랜치에서 분기한 것을 확인할 수 있다. 이제 o2 브랜치에서 작업이 다 끝났다고 가정하고, o2 브랜치의 내용을 master 브랜치로 병합한다고 해보자. 브랜치를 병합하려면 먼저 master 브랜치로 switch 해야한다. 

$ git switch master

 

브랜치를 병합하려면 git merge 다음에 가져올 브랜치 이름을 적는다.

$ git merge o2

 
참고) 빨리 감기 병합 (fast-forward merge)

master 브랜치에서 분기한 후에 master 브랜치에 아무 변화가 없다면 분기한 브랜치에서 만든 최신 커밋을 master 브랜치가 가리키게만 하면 된다. 따라서 git merge 명령의 결과가 단순히 포인터를 움직인 것이기 때문에 커밋 메시지 창은 따로 열리지 않는다. 

 

2) 같은 문서의 다른 위치를 수정했을 때 병합하기

master 브랜치와 o2 브랜치에는 똑같이 work.txt 파일이 있다. 같은 파일의 다른 위치를 수정하고 병합했을 때 어떤 결과가 나오는지 알아보자.

 

새로운 디렉터리 생성
master 브랜치에서 work.txt
o2 브랜치에서 work.txt

이제 병합한다. 단, 병합은 master 브랜치에서 해야한다.

$ git merge o2

Auto-merging work.txt 문구를 확인할 수 있다.

자동으로 하나의 파일에 합쳐진 것을 볼 수 있다.

 

3) 같은 문서의 같은 위치를 수정했을 때 병합하기

각 브랜치에 같은 파일 이름을 가지고 있으면서 같은 줄을 수정했을 때 브랜치를 병합하면 브랜치 충돌(conflict)가 발생한다.

 

새로운 디렉토리 생성
master 브랜치에서 work.txt
o2 브랜치에서 work.txt

master 브랜치와 o2 브랜치에서 같은 파일의 같은 위치를 수정한 것을 확인할 수 있다. 이때 병합하게 되면 브랜치 충돌(conflict)가 발생하고 그 결과를 알아보자.

 

$ git switch master
$ git merge o2

CONFLICT 메시지를 확인할 수 있다. 자동 병합하는 동안 충돌이 발생했다는 뜻이다. 충돌이 생긴 문서는 자동으로 병합될 수 없으므로 사용자가 직접 충돌 부분을 해결한 후 커밋해야 한다. 

 

참고)

만일 여러 개의 파일을 병합했다면 충돌이 발생한 파일 외에 다른 파일들은 자동으로 master 브랜치에 병합된다.

 

$ vim work.txt

직접 수정
수정 후 커밋

$ git log --oneline --branches --graph

 

4) 병합이 끝난 브랜치 삭제하기

현재 2개의 브랜치를 확인할 수 있다.

저장소의 기본 브랜치는 master이므로 브랜치를 삭제하려면 master 브랜치에서 해야한다.

 

5. 브랜치 관리하기

1) 브랜치에서 switch와 reset의 작동 원리

HEAD는 현재 작업 트리(working directory)가 어떤 버전을 기반으로 작업 중인지를 가리키는 포인터이다. 현재 작업중인 브랜치를 가리킨다고 생각하면 된다. 그리고 브랜치는 기본적으로 브랜치에 담긴 커밋 중에서 가장 최신 커밋을 가리킨다. 

 

다음 커밋로그를 보면 HEAD는 master 브랜치를 가리키고, master 브랜치는 가장 최신 커밋인 c1 커밋을 가리킨다. 

 

이제 sub 브랜치를 생성한다. 그러면 sub브랜치 또한 c1 커밋을 가리킨다.

$ git branch sub

master 브랜치에서 c2.txt 파일을 만들고, 'c2' 메시지로 커밋한다.

 

sub 브랜치로 switch 후에 s1.txt 파일을 만들고 's1' 메시지로 커밋한다.

 

여기서 커밋로그와 브랜치 상태은 다음과 같다.

$ gir reset [커밋 해시]

커밋해시는 4글자까지만 입력해도 된다. sub 브랜치에서 최신 커밋을 c2 커밋으로 바꾼다.

 

sub 브랜치는 c2 커밋을 가리키고 있게 되었으므로 원래 가리키고 있던 s1 커밋은 연결이 끊기면서 삭제된다.

 

정리)

1. git switch 명령을 사용하면 HEAD를 제어해서 브랜치를 이동할 수 있다.

2. git reset 명령을 사용하면 HEAD가 가리키고 잇는 브랜치의 최신 커밋을 원하는 커밋으로 지정할 수 있다.

3. 이때 어떤 브랜치에 잇는 커밋이든 지정할 수 있다.

4. 명령을 수행한 뒤 브랜치와 연결이 끊긴 커밋은 삭제된다.

 

2) 수정 중인 파일 감추기 및 되돌리기 - git stash

먼저, git stash 명령을 사용하려면 파일이 tracked 상태여야 한다.

 

현재 깃의 상태

$ git stash

git stash 후 깃의 상태

f1.txt 파일과 f2.txt 파일이 사라진 것은 아니다. 그러나 조금 전에 나타나던 modified 메시지가 사라진 것을 확인할 수 있다. 같은 방법으로 여러 파일을 수정한 후 따로 보관할 수 있으며, 이렇게 감춘 파일은 stash 목록에서 확인할 수 있다. 해당 stash 목록은 스택 자료구조이며 가장 최근에 보관한 것인 stash@{0}에 담긴다.

$ git stash list

 

감춰둔 파일을 꺼내와 계속 수정할 때는 git stash 다음에 pop을 입력한다. stash 목록에서 가장 최근 항목을 되돌린다.

$ git stash pop

 

참고) stash apply와 stash drop

git stash apply는 stash 목록에서 가장 최근 항목을 되돌리지만 저장했던 내용은 그대로 남겨둔다.

$ git stash apply

 

git stash drop은 stash 목록에서 가장 최근 항목을 삭제한다.

$ git stash drop
반응형