반응형

브랜치 모델은 Git이 지닌 최고의 장점이라 할 수 있습니다.
브랜치는 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발할 수 있게 해줍니다.

 

1. 브랜치란 무엇인가

Git이 브랜치를 다루는 과정을 이해하려면 우선 Git이 데이터를 어떻게 저장하는지 알아야 합니다.

Git은 데이터를 Change Set이나 변경사항으로 기록하지 않고 일련의 스냅샷으로 기록한다는 것을 [What is Git?] 에서 살펴봤습니다.

 

커밋하면 Git은 현재 Staging Area 에 있는 데이터의 스냅샷에 대한 포인터, 저자나 커밋 메시지 같은 메타데이터, 이전 커밋에 대한 포인터 등을 포함하는 커밋 개체를 저장합니다.

여기서 이전 커밋 포인터가 있기 때문에 현재 커밋이 무엇을 기준으로 바뀌었는지를 알 수 있습니다. 최초 커밋을 제외한 나머지 커밋은 이전 커밋 포인터가 적어도 하나씩 있고 브랜치를 합친 Merge 커밋 같은 경우에는 이전 커밋 포인터가 여러 개 있습니다.

 

Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것입니다. 기본적으로 Git은 master 브랜치를 만듭니다. 처음 커밋하면 이 master 브랜치가 생성된 커밋을 가리킵니다. 이후 커밋을 만들면 master 브랜치는 자동으로 가장 마지막 커밋을 가리킵니다.

 

Git 버전 관리 시스템에서 master 브랜치는 특별하지 않습니다. 다른 브랜치와 다른 것이 없습니다. 다만 모든 저장소에서 master 브랜치가 존재하는 이유는 git init 명령으로 초기화할 때 자동으로 만들어진 이 브랜치를 애써 다른 이름으로 변경하지 않기 때문입니다.

 

2. 새 브런치 생성하기

git branch 명령으로 새로운 브랜치를 만들 수 있습니다.

기존에 작업하고 있던 master 브랜치에서 testing 이라는 브랜치를 만들어보겠습니다.

$ git branch testing

위 명령을 실행하면 새로 만든 브랜치도 지금 작업하고 있던 마지막 커밋을 가리킵니다.

그림 1. 한 커밋 히스토리를 가리키는 두 브랜치

지금 작업 중인 브랜치가 무엇인지 Git은 어떻게 파악할까요?

 

다른 버전 관리 시스템과는 달리 Git은 HEAD 라는 특수한 포인터가 있습니다. 이 포인터는 지금 작업하는 로컬 브랜치를 가리킵니다. 브랜치를 새로 만들었지만, Git은 아직 master 브랜치를 가리키고 있습니다. 이렇듯 git branch 명령은 브랜치를 만들기만 하고 HEAD가 가리키는 브랜치를 옮기지 않습니다.

그림 2. 현재 작업 중인 브랜치를 가리키는 HEAD

 

3. 브랜치 이동하기

git branch 명령은 브랜치를 생성할 뿐 HEAD 가 가리키는 브랜치를 옮기지는 않는다고 했습니다.

그렇다면 브랜치는 어떻게 이동할 수 있을까요?

git checkout 명령으로 다른 브랜치로 이동할 수 있습니다. 한번 testing 브랜치로 바꿔보겠습니다.

$ git checkout testing

이렇게 하면 HEAD는 testing 브랜치를 가리킵니다.

그림 3. HEAD가 testing 브랜치를 가리킴

 

자, 이제 브랜치의 핵심을 살펴볼 수 있습니다.

커밋을 새롭게 한 번 해보겠습니다.

$ vim test.rb
$ git commit -a -m 'made a change'

그림 4. HEAD가 가리키는 testing 브랜치가 새 커밋을 가리킴

 

새로 커밋해서 testing 브랜치는 앞으로 이동했습니다. 하지만, master 브랜치는 여전히 이전 커밋을 가리킵니다. 그렇다면 이번엔 master 브랜치로 되돌아가보겠습니다.

$ git checkout master

그림 5. HEAD가 checkout 한 브랜치로 이동함

 

방금 실행한 명령이 한 일은 두 가지입니다.

master 브랜치가 가리키는 커밋을 HEAD가 가리키게 하고, 워킹 디렉토리의 파일도 그 시점으로 되돌려 놓았습니다. 앞으로 커밋을 하면 다른 브랜치의 작업들과 별개로 진행되기 때문에 testing 브랜치에서 임시로 작업하고 원래 master 브랜치로 돌아와서 하던 일을 계속할 수 있습니다.

 

브랜치를 이동하면 워킹 디렉토리의 파일이 변경됩니다.

이전에 작업했던 브랜치로 이동하면 워킹 디렉토리의 파일은 그 브랜치에서 가장 마지막으로 했던 작업 내용으로 변경됩니다. 파일 변경시 문제가 있어 브랜치를 이동시키는게 불가능한 경우 Git은 브랜치 이동 명령을 수행하지 않습니다.

이번에는 master 브랜치에서 파일을 수정하고 커밋을 해보겠습니다.

$ vim test.rb
$ git commit -a -m 'made other changes'

이렇게 되면 프로젝트 히스토리는 분리되어 진행합니다.(브랜치가 갈라집니다.)

두 작업 내용은 서로 독립적으로 각 브랜치에 존재합니다. 커밋 사이를 자유롭게 이동하다가 때가 되면 두 브랜치를 Merge 하면 됩니다.

그림 6. 갈라지는 브랜치

 

실제로 Git의 브랜치는 어떤 한 커밋을 가리키는 40글자의 SHA-1 체크섬 파일에 불과하기 때문에 만들기도 쉽고 지우기도 쉽습니다. 새로 브랜치를 하나 만드는 것은 41바이트 크기의 파일을(40자와 줄 바꿈 문자) 하나 만드는 것에 불과합니다.

 

브랜치가 필요할 때 프로젝트를 통째로 복사해야 하는 다른 버전 관리 도구와 Git의 차이는 극명합니다. 통째로 복사하는 작업은 프로젝트 크기에 따라 다르겠지만 수십 초에서 수십 분까지 걸립니다. 그에 비해 Git은 순식간입니다.

게다가 커밋을 할 때마다 이전 커밋의 정보를 저장하기 때문에 Merge 할 때 어디서부터(Merge Base) 합쳐야 하는지 압니다. 이런 특징은 개발자들이 수시로 브랜치를 만들어 사용하게 합니다.


출처 - 저서 ProGit

반응형
반응형