[Git] 브랜치란?

git의 작동 과정

git은 데이터를 일련의 스냅샷의 연속으로 저장한다. 그 과정은 어떻게 될까? 파일이 3개 있는 디렉토리가 하나 있고, 이 파일을 add, commit하는 예제를 살펴보자.

  1. add(ex:$ git add README test.rb LICENSE)

    파일을 stage하면 git저장소에 파일을 저장(=Blob)하고, staging area에 해당 파일의 체크섬을 저장한다.

  2. commit(ex:$ git commit -m 'The initial commit of my project')

    커밋을 진행하면 먼저 루트 디렉토리와 각 하위 디렉토리의 트리 개체를 체크섬과 함께 저장소에 저장한다.

    이후 커밋 개체를 만들고, 메타데이터와 루트 디렉토리 트리 개체를 가리키는 포인터 정보를 커밋 개체에 넣어 저장한다.(덕분에 언제든지 스냅샷을 다시 만들 수 있다.)

    git저장소에는 다섯 개의 데이터 개체가 생성될 것이다

    • 각 파일에 대한 Blob 3개
    • 파일과 디렉토리 구조가 들어있는 트리 개체 하나
    • 메타데이터와 루트 트리를 가리키는 포인터가 담긴 커밋 개체 하나

    Untitled

    우측부터 Blob 3개, 트리개체, 커밋 개체 순서이다.

  3. 파일을 수정하고 커밋하면 이전 커밋이 무엇인지도 저장한다.

    Untitled

    가장 왼쪽이 최초 커밋이다. 다음 커밋들은 모두 이전 커밋이 무엇인지 알고있다.


그래서 Branch란?

git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것이다. 브랜치는 서로 영향을 받지 않기 때문에, 독립적으로 작업하는데 사용한다.

Untitled

🌟master branch란?git init 명령으로 초기화 할 때 기본적으로 생성되는 브랜치. 자동으로 마지막 커밋을 가리킨다.

Untitled

git branch <브랜치이름>명령어를 통해 새로운 브랜치를 생성할 수 있으며, 새로 생성된 브랜치는 지금 작업하고 있는 마지막 커밋을 가리킨다.

Untitled

그림만 보면 현재 작업중인 브랜치가 무엇인지 알 수 없다. 이를 구별하기 위하여 git은 ‘HEAD’라는 포인터를 사용한다. 만약 브랜치가 어떤 커밋을 가리키는지 확인하고 싶다면, git log --decorate를 사용하면 된다.

Untitled

현재 브랜치에서 다른 브랜치로 옮기고 싶다면 $ git checkout명령어를 사용하라. 위의 그림은 $ git checkout testing명령어를 실행 후, 새롭게 커밋을 한 상황이다. HEAD가 testing 브랜치를 가리키고 있다. master 브랜치는 이전의 위치에 머무르는 모습이다.

Untitled

여기서 다시 master 브랜치로 이동하면 어떻게 될까? HEAD가 master 브랜치를 가리키며, 워킹 디렉토리의 파일도 그 시점으로 되돌아간다. 반대로 말하면 파일 변경에 문제가 있을 시 브랜치의 이동이 불가능하다.

Untitled

위의 상황에서 파일을 수정하고 커밋하였다. 다른 브랜치와는 별개로 작업이 진행되는 모습이다. 두 작업 내용은 서로 독립적으로 각 브랜치에 존재한다. 이렇게 작업을 진행하다 때가 되면 두 브랜치를 병합한다.

브랜치가 갈라진 시기는 git log를 통해 확인할 수 있다. $ git log --oneline --decorate --graph --all명령어를 실행해 보자.


브랜치의 장점은?

매우 가볍다. 앞서 말했듯 브랜치는 일종의 포인터이다. 어떤 한 커밋을 가리키는 40글자의 체크섬 파일에 불과하기에, 생성과 삭제가 매우 간단하다.

참고자료