본문 바로가기
기타/git

[Git] 깃의 브랜치 사용법

by 책 읽는 개발자_테드 2021. 5. 10.
반응형

'Do it! 지옥에서 온 문서관리자 깃&깃허브 입문'을 정리, 요약하여 깃의 브랜치 기능을 설명하는 글입니다.

www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791163031222&orderClick=LAG&Kc=

 

학습 목표

- 브랜치는 왜 필요한 것일까?

- 브랜치의 기능

- 브랜치 만들기, git branch

- 브랜치 사이 이동하기, git checkout

- 브랜치 정보 확인하기

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

- 브랜치 병합하기

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

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

 


브랜치는 버전 관리 시스템에서 나무 가지(브랜치)처럼 여러 갈래로 퍼지는 데이터 흐름을 말한다.

브랜치는 왜 필요한 것일까?

 

 기존 파일에 소스 코드를 추가해서 새로운 버전을 만든다고 생각하자. 새로운 기능을 추가했을 때 오류 없이 동작한다는 보장이 없다면, 제대로 동작하는 소스는 그대로 둔 채 새 소스를 추가한 버전을 따로 만들어 관리하고, 완벽하게 완성한 다음 원래 소스에 더할 수 있다면 편리할 것이다.

 

이럴 때 사용하는 방법이 깃의 ‘브랜치(분기)’라는 기능이다.



브랜치의 기능

 

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

 

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

 

이렇게 master 브랜치에서 뻗어 나오는 새 브랜치를 만드는 것을 분기(branch)라고 한다.

 

분기했던 새 브랜치에 원하는 작업을 다 끝낸 후 새 브랜치에 있던 파일을 원래 master 브랜치에 합치는 것을 병합(merge)이라 한다.

 

브랜치 만들기, git branch

 

터미널 창에서 manual이라는 새 디렉터리를 만들고 해당 디렉터리로 이동한다.

 

$ mkdir manual
$ cd manual

 

manual 디렉터리를 저장소로 만들고 ls -al 명령을 사용해서 .git 디렉터리가 만들어졌는지 확인한다.

 

$ git init
$ ls -al

 

manual 디렉토리 안에 work.txt 파일을 만들고, ‘content 1’이라는 내용을 입력 ·저장한다.

 

work.txt 파일을 스테이지에 올리고 커밋한다. 커밋 메시지: work 1

 

$ git add work.txt
$ git commit -m “work 1”

 

work.txt 파일에 ‘content 2’라는 내용을 추가한 후 두 번째 커밋을 한다. 커밋 메시지: work 2

$ git commit -am "work 2"

 

work.txt 파일에 ‘content 3’을 추가한 후 ‘work 3’라는 메시지와 함께 커밋한다.

$ git commit -am "work 3"

 

 

git log를 입력해서 커밋 내역을 확인한다. 최신 커밋인 “work 3”을 가리키고, HEAD가 master 브랜치를 가리킨다. 

 

HEAD는 현재 작업 중인 브랜치를 가리킨다.

 

 

이제 부터 apple, google, ms라는 고객사가 있다고 가정하고, 브랜치를 통해 여러 고객사에게 서로 다른 내용의 사용 설명서를 제공하는 작업을 하자.

 

git branch는 깃에서 브랜치를 만들거나 확인하는 명령어다. 이것을 사용하면, 저장소를 만들 때 기본으로 만들어지는 master 브랜치가 보인다.

$ git branch

 

새로운 브랜치를 만들려면, ‘git branch 브랜치이름’을 입력한다.

$ git branch apple

 

다시 현재 저장소에 브랜치를 확인하면, master 브랜치 위에 apple 브랜치가 추가되었다. 브랜치 앞에 * 표시는 해당 브랜치에서 작업하고 있다는 뜻이다.

 

git log를 입력하면, (HEAD-> ,master)라고 표시되던 곳에 apple 브랜치가 추가된 걸 확인할 수 있다. 이 표시는 저장소에 master, apple 2개의 브랜치가 있고, HEAD -> master이므로 현재 작업 중인 브랜치는 master 브랜치라는 의미다.

 

 

같은 방법으로 goole, ms 브랜치는 만든다.

$ git branch google
$ git branch ms
$ git branch



브랜치 사이 이동하기, git checkout

 

현재 위치한 브랜치는 master 브랜치다. 커밋을 하나 만들어 어떻게 달라지는지 확인한다. work.txt 파일에 ‘master content 4’라는 내용을 추가한 후 커밋한다. 커밋 메시지: master work 4

$ git commit -am "master work 4"

 

git log 명령어에 --oneline 옵션을 추가해서 커밋 로그를 확인한다. --oneline 옵션은 한 줄에 한 커밋씩 커밋을 간략히 보여준다.

$ git log --oneline

 

최신 커밋인 ‘master work 4’는 master 브랜치에만 적용되었고, ms, google, apple 브랜치는 아직 ‘work 3’ 커밋 상태다.

현재 브랜치(master)에서 다른 브랜치로 이동해보자. git checkout 명령과 브랜치 이름을 사용한다. 그래서 다른 브랜치로 이동하는 것을 ‘X 브랜치로 체크아웃한다'고 말한다. 

$ git checkout apple
$ git branch

 

작업 브랜치를 바꿨을 때 어떤 변화가 생기는지 확인하자.

$ git log --oneline

 

master 브랜치에서 apple 브랜치를 분기하기 전까지 master 브랜치에 있던 커밋들은 그대로 apple 브랜치에 복사되어 있다. 그리고 최신 커밋 해시에서 HEAD가 apple을 가리키고 있다.

 

이번에는 work.txt 파일 내용을 확인해보자.

$ cat work.txt

 

최신 커밋이 work3이기 때문에 content1 부터 content3까지 세 개의 행만 있다. 

 

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

 

 

브랜치 정보 확인하기

 

여러 브랜치에서 각각 커밋이 발생할 때 커밋끼리 어떤 관계를 갖는지 확인하는 방법과 브랜치 사이의 차이점을 확인하는 방법을 알아보자.

 

위에서 체크아웃한 apple 브랜치에 work.txt 파일에 ‘apple content 4’라는 텍스트를 추가하고 저장한다. 그리고 apple.txt라는 새로운 파일도 만들어서 동일하게 ‘apple content 4’라는 텍스트를 추가하고 저장한다.

 

git add 뒤에 마침표(.)를 추가하여 수정된 파일들을 한번에 스테이지에 올리고, 커밋한다. 

커밋 메시지: apple content 4

 

$ git add .

$ git commit -m “apple content 4”

$ git add .
$ git commit -m “apple content 4”

 

커밋이 어떻게 저장되었는지 git log 명령으로 확인한다.

$ git log --oneline

 

첫 번째 줄(HEAD -> apple)을 통해 apple 브랜치에 체크아웃한 상태이고, apple 브랜치의 최신 커밋은 ‘apple content 4’임을 알 수 있다.

 

✍ git log 명령을 사용할 때 --branche 옵션을 사용하면 각 브랜치의 커밋을 함께 볼 수 있다.

$ git log --oneline --branches

✍ 브랜치와 커밋의 관계를 보기 쉽게 그래프 형태로 표시하려면 git log --graph 옵션을 사용한다.

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

 

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

 

✍ 브랜치 이름 사이에 마침표 두 개(..)를 넣는 명령으로 브랜치 브랜치 사이의 차이점을 쉽게 확인할 수 있다.

$ git log master..apple

 

이렇게 하면 master 브랜치에는 없고 apple 브랜치에만 있는 커밋( ‘apple content 4’)을 보여준다.

 

반대로 적용해보자.

$ git log apple..master

 

이렇게 하면 apple 브랜치에는 없고 master 브랜치에만 있는 커밋(‘master content 4’)을 보여준다.



브랜치 병합하기

 

만들어진 각 브랜치에서 작업을 하다가 어느 시점에는 브랜치 작업을 마무리하고 기존 브랜치와 합해야 한다. 이것을 “브랜치 병합(merge)”이라고 한다.

 

서로 다른 파일 병합하기

✍터미널에서 manual-2라는 디렉터리를 만든 후 저장소를 초기화 한다.

$ mkdir manual-2
$ cd manual-2
$ git init 
$ ls -al

 

✍ manual-2 디렉터리에 숫자 ‘1’이 저장된 work.txt 파일을 만들고, 커밋한다. 커밋메시지: work 1

 



✍’o2’ 브랜치를 만든다.

$ git branch o2

 

✍ 현재 master 브랜치에 ‘master 2’라는 내용의 master.txt 파일을 만들고, 커밋한다. 

커밋메시지: master work 2



✍ o2 브랜치로 체크아웃한다.

$ git checkout o2

 

✍ o2 브랜치에서 ‘o2 work 2’라는 내용의 o2.txt라는 파일을 만들고, 커밋한다.



✍ 현재 커밋 상태를 확인하면, 커밋 ‘work 1’은 master 브랜치와 o2 브랜치 모두 가지고 있다. 그리고 master 브랜치에는 ‘master work 2’ 커밋이, o2 브랜치에는 ‘o2 work 2’ 커밋이 생겼다.



✍이제 o2 브랜치의 내용을 master 브랜치로 병합하자.

 

먼저 master 브랜치로 체크아웃한다.

$ git checkout master

 

그리고 브랜치 병합을 위해 git merge 명령 뒤에 가져올 브랜치 이름을 적는다.

$ git merge o2

 

자동으로 편집기가 실행되고, ‘Merge branch o2’ 커밋 메시지가 나타난다. 커밋 메시지를 수정하거나, 자동 메시지를 그대로 사용해서 내용을 저장한다. (vim의 경우 :wq)

 

만약 편집기 창을 열지 않고 깃에서 지정하는 커밋 메시지를 그대로 사용하려면 --no-edit 옵션을 추가한다.

$ git merge o2 --no-edit

 

✍ 커밋 상태를 확인하면, 다음과 같은 구조를 갖는다.

 

 

✍la -al 명령을 사용해보자. o2 브랜치에 있던 o2.txt 파일이 master 브랜치에 합쳐졌다.



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

 

위에서 생성한 master 브랜치와 o2 브랜치는 똑같이 work.txt 파일이 있다. 양쪽 브랜치에서 work.txt 문서의 서로 다른 위치를 수정한 후 브랜치를 병합하고, 결과를 확인하자.

 

홈 디렉터리로 이동하여 manual-3라는 깃 저장소를 만든다.

$ mkdir manual-3
$ cd manual-3
$ git init 

 

 

work.txt 파일을 만들고, 중간에 두 줄 공백이 있게 다음과 같이 작성한다.

 

 

 

work.txt 파일을 스9테이지에 올리고 커밋한다. 커밋 메시지: work 1

$ git add work.txt
$ git commit -m "work 1"

 

▶ o2라는 새로운 브랜치를 만든다.

$ git branch o2

 

▶ master 브랜치에서 work.txt를 다음과 같이 수정(‘master content 2’ 추가)하고, 커밋한다. 커밋 메시지: master work 2

 

$ git commit -am “master work 2”


▶ 이번에는 o2 브랜치로 체크아웃해서 work.txt 파일을 수정(‘o2 content 2’ 추가)하고 커밋한다. 커밋 메시지: o2 work 2

$ git checkout o2 
$ vim work.txt

$ git commit -am "o2 work 2"

 

▶  master 브랜치와 o2 브랜치 양쪽에서 work.txt 파일의 수정한 위치는 서로다르다. 이제 master 브랜치로 체크아웃하여 o2브랜치를 master 브랜치에 합치자.

$ git checkout master
$ git merge o2



▶ work.txt 파일을 확인해보면, master 브랜치의 수정 내용과 o2 브랜치의 수정 내용이 자연스럽게 하나의 파일에 합쳐진 것을 볼 수 있다.

 

 

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

 

깃에서는 줄 단위로 변경 여부를 확인한다. 이때 각 브랜치에 같은 파일,  같은 줄을 수정하면 브랜치에 충돌이 발생한다.

 

master 브랜치와 o2 브랜치에서 같은 파일, 같은 위치를 수정 후 병합하여 충동을 발생시키고, 이를 해결해보자.

 

▶ manual-4라는 깃 저장소를 만들고, 해당 디렉토리로 이동한다.

$ mkdir manual-4
$ cd manual-4
$ git init

 

▶ 내용 사이에 빈 줄이 존재하는 work.txt 파일을 만든 후 스테이징&커밋한다. 커밋 메시지: work 1

$ touch work.txt

 

$ git add work.txt
$ git commit -m "work 1"

 

▶ o2 브랜치를 만들고, 체크아웃 하지 않은 상태로 work.txt를 수정하고(빈 줄에 master content 2 입력), 커밋한다 .

커밋 메시지: master work 2

$ git commit -am "master work 2"

 

▶ o2 브랜치로 체크아웃한다.

$ git checkout o2

 

▶ master 브랜치에 내용을 추가했던 위치에 “o2 content 2”라고 입력하고 저장 후 커밋한다. 커밋 메시지: o2 work 2

$ git commit -am "o2 work 2"

 

▶ master 브랜치, o2 브랜치에서 work.txt 파일의 수정 위치는 같다. 이제 master 브랜치로 체크아웃하고, 둘을 병합한다.

$ git checkout master
$ git merge o2

 

▶ 병합을 위해 merge 명령어를 사용하면, 충돌이 발생한다.

 

▶ work.txt 파일을 열어보면, 다음과 같이 변경되어있다. ‘<<<<<<< HEAD’와 가로줄(=======) 사이에 내용은 현재 브랜치(master)에서 수정한 내용이다. 가로줄(=======)과 ‘>>>>>>> o2’ 사이의 내용은 o2 브랜치에서 수정한 내용이다.

 

▶ 원하는 내용으로 work.txt 파일을 수정하고 ‘<<<<<<< HEAD’, 가로줄(=======), ‘>>>>>>> o2’은 삭제한다. 

 

▶ 수정한 work.txt를 스테이징&커밋한다. 이렇게 충돌을 해결했다. 

커밋 메시지: merge o2 branch

$ git commit -am "merge o2 branch"

 

▶ 다음과 같이 지금까지 만든 브랜치와 커밋 관계를 한눈에 확인할 수 있다.

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

 

브랜치 병합 후 더 이상 사용하지 않는 브랜치를 branch 명령어에 -d 옵션을 사용해서 삭제한다.

$ git branch -d o2

 

같은 이름으로 다시 브랜치를 만들면 예전에 작업했던 내용이 나타난다. 즉, 브랜치를 삭제해도 완전히 저장소에서 없어지지 않고, 흐름 속에서만 감추는 것이다.

 

반응형

댓글