Git

브랜치

bde574786 2025. 3. 7. 16:51

브랜치 특징

가상 폴더

깃의 브랜치는 작업 폴더를 실제로 복사하지 않고, 가상 폴더로 생성한다. 외부적으로는 물리적인 파일 하나만 있는 것으로 보인다. 생성된 작업 폴더는 물리적으로 복제된 구조보다 유연하게 처리할 수 있다. 브랜치로 생성된 가상 폴더는 빠르게 공간 이동이 가능하다. 개발자는 쉽게 가상 폴더인 브랜치를 이동하면서 프로젝트를 수행할 수 있다.

 

독립적인 동작

브랜치를 이용하면 원본 폴더와 분리하여 독립적으로 개발 작업을 수행할 수 있다. 기존에는 소스 코드의 작업 폴더를 별도로 생성했다. 물리적으로 복사된 각자의 폴더에서 코드를 작업한 후 소스 코드 2개를 다시 하나로 합쳐야 했다. 코드를 하나라 합치려면 작업 내역들을 일일이 찾아 정리해야 한다.

하지만, 깃과 같은 버전 관리 시스템을 이용하면 분리된 코드를 좀 더 쉽게 병합할 수 있다. 분리된 브랜치에서 소스 코드를 각자 수정한 후 원본 코드에 병합하는 명령만 실행하면 된다. 깃의 브랜치는 규모가 큰 코드 수정이나 병합을 처리할 때 매우 유용하다.

 

빠른 동작

깃의 브랜치 기능은 다른 버전 관리 도구보다 가볍고, 브랜치 전환이 빠른 것이 특징이다. 깃은 Blob 개념을 도입하여 내부를 구조화한다.

브랜치 명령을 사용하면 내부적으로 커밋을 하나 생성하여 브랜치로 할당한다. 다른 버전 관리 시스템은 폴더의 파일 전체를 복사하는 반면, 깃은 41바이트를 가지는 해시(SHA1) 파일 하나만 만들면 되므로 브랜치를 더 빠르게 생성할 수 있다.

 

저장소 생성 및 초기화

깃 배시에서 초기화 명령을 실행하면 다음과 같이 터미널 프롬프트 창에 현재 브랜치 이름이 같이 출력된다. 현재 브랜치가 master라는 것을 확인할 수 있다. 깃 배시는 리눅스 명령을 사용할 수 있고, 현재 브랜치의 작업 위치도 쉽게 알 수 있다.

 

기본 브랜치

모든 커밋과 이력은 브랜치에 기록된다. 깃은 최소한 브랜치가 1개 이상 필요하다. 따라서 저장소를 처음 초기화하면 master 브랜치 하나가 자동으로 생성된다. 첫 번째 커밋은 master 브랜치에서 시작한다.

status 명령어의 출력 결과 메세지에서 "On branch master"를 확인할 수 있다. 깃에서는 항상 현재 작업하는 브랜치 위치를 확인하는 것이 중요하다.

 

또는 저장소에 존재하는 브랜치 목록을 보여주는 branch 명령어로 현재 브랜치를 확인할 수 있다. 깃의 브랜치는 기본적으로 커밋을 가리키는 포인터이지만 초기화 직후 커밋이 하나도 없다면 브랜치가 가리킬 대상이 없으므로 브랜치가 확정된 상태가 아니다. 따라서, 커밋이 하나도 없다면 git branch 명령어를 실행했을 때 아무것도 나오지 않는다. 첫 커밋을 한다면 브랜치가 커밋을 가리킬 수 있게 되면서 실제 브랜치처럼 동작하게 된다.

반면, branch 명령의 --show-current 옵션을 사용하면 단순히 현재 체크아웃된 브랜치의 이름을 보여주기 때문에 커밋이 없어도 현재 브랜치 이름을 출력한다.

$ git branch  # 커밋이 없다면 출력 결과가 없음
$ git branch --show-current  # 커밋이 없어도 브랜치 이름을 출력

 

브랜치 생성

브랜치는 가상의 작업 폴더이다. 처음 깃을 초기화 할 때 워킹 디렉토리는 master 브랜치를 생성한다. 브랜치를 생성하려면 기준이 되는 브랜치 또는 커밋이 하나 있어야 한다. 그리고 깃은 master 브랜치를 기준으로 새로운 브랜치를 생성한다.

브랜치는 공통된 커밋을 가리키는 지점이다. 그리고 브랜치는 커밋처럼 SHA1 해시키를 가리킨다. 하지만 커밋의 SHA1 해시키는 기억하기 어렵기 때문에 특정 커밋의 별칭을 만들고 이렇게 만든 별칭이 브랜치인 것이다. 즉, 브랜치를 생성한다는 의미는 기존 브랜치 또는 커밋에 새로운 연결 고리를 하나 더 만드는 것과 같다.

브랜치는 깃에서 또 하나의 개발 분기점을 의미한다. 새로운 개발 분기점이 필요할 때는 브랜치를 추가로 생성할 수 있다. 브랜치 생성 개수에는 제한이 없다.

브랜치를 생성할 때는 branch 명령어를 사용한다. 브랜치 이름만 입력하면 현재 HEAD 포인터를 기준으로 새로운 브랜치를 생성한다. 이렇게 새로운 브랜치를 만들면 브랜치를 생성하기 직전의 브랜치가 기준이 되어 같은 커밋에서 시작한다.

$ git branch 브랜치이름
$ git branch 브랜치이름 커밋ID

 

브랜치 이름

브랜치 이름을 지을 때 사전 예약된 명칭은 따로 없지만 해당 브랜치 작업이 알기 쉬운 이름으로 짓는 것이 좋다. 또는 깃 git flow에서 정의한 브랜치 이름을 적용하는 것도 좋은 방법이다. 브랜치 이름을 중복해서 사용하지 않도록 주의한다.

작성 규칙

  • 하이픈(-), 마침표(.) 기호로 시작할 수 없다.
  • 연속적인 마침표(..)를 포함할 수 없다.
  • 빈칸, 공백 문자, 물결(~), 캐럿(^), 물음표(?), 별표(*), 대괄호([]) 등은 포함할 수 없다.
  • 아스키 제어 문자는 포함할 수 없다.

 

브랜치 확인

브랜치 목록을 확인하려면 branch 명령어만 입력하면 된다. branch 명령어는 단독으로도 실행할 수 있다. 현재 모든 브랜치가 나열되며 * 표시는 현재 선택된 브랜치를 의미한다.

$ git branch

 

브랜치 해시

브랜치는 특정한 커밋의 해시값(SHA1)을 가리킨다. 깃의 저수준 명령어인 rev-parse를 사용하면 현재 브랜치가 어떤 커밋 해시값을 가리키는지 확인할 수 있다.

$ git rev-parse 브랜치이름

 

브랜치의 해시값과 브랜치를 생성한 기준 커밋의 해시값이 동일하다. 브랜치가 커밋의 해시를 기준으로 생성된다는 것을 다시 한 번 알 수 있다.

 

브랜치 세부 사항 확인

기본적인 branch 명령어는 간단한 브랜치 이름만 출력하지만 v(verbose) 옵션을 사용하면 브랜치 이름, 커밋 ID, 커밋 메세지를 같이 볼 수 있다.

$ git branch -v
$ git branch --verbose

 

체크아웃

브랜치로 체크아웃

깃에서 브랜치 간 이동할 때는 checkout 명령어를 사용한다. 현재 브랜치를 떠나 새로운 브랜치로 들어간다는 의미이다. 브랜치 이름은 커밋 해시키와 동일하므로 브랜치 이름 대신 커밋 해시키를 사용하여 체크아웃 할 수 있다.

$ git checkout 브랜치이름
$ git checkout 커밋해시키

 

워킹 디렉토리는 선택한 브랜치 하나만 연결되어 있다. 즉, 한 브랜치에서만 작업과 커밋을 할 수 있다. 따라서, 다른 브랜치에서 작업하려면 반드시 브랜치를 변경하여 워킹 디렉토리를 재설정해야 한다.

 

브랜치를 변경하려면 기존 브랜치의 워킹 디렉토리를 정리하지 않고서는 브랜치를 변경할 수 없다. 워킹 디렉토리에서 작업하다 커밋하지 않고 남겨 둔 상태에서 다른 브랜치로 체크아웃하면 이처럼 브랜치 이동이 제한된다. 깃은 향후 충돌을 방지하기 위해 워킹 디렉토리에 작업이 남아있다면 경고 메세지를 보여주고 브랜치 변경을 제한한다. 따라서, 브랜치 간에 정상적으로 이동하려면 수정된 내용을 커밋해야 한다. 작업된 워킹 디렉토리를 커밋하지 않고 브랜치를 변경할 때는 스태시 기능을 사용하면 좋다.

 

HEAD를 활용한 체크아웃

커밋의 해시키를 사용하여 체크아웃하려면 복잡한 해시키를 알고 있어야 하고 입력 오류도 많이 생길 수 있다. 좀 더 간편하게 HEAD 포인터를 사용하여 체크아웃 할 수도 있다.

$ git checkout HEAD~1
$ git checkout HEAD~5

 

브랜치를 체크아웃하면 Detached 상태가 되지 않지만 특정 커밋을 직접 체크아웃하면 특정 브랜치에 속해 있지 않는 Detached 상태가 된다. 깃에서 HEAD는 보통 브랜치를 가리키지만, 특정 커밋을 직접 가리키고 있기 때문이다. 이러한 경우 새 브랜치를 만들고, 현재 Detached 상태의 커밋을 가리키게 하거나 원래 브랜치로 돌아가는 방법이 있다.

 

파일로 체크아웃

파일 단위로 체크아웃하는 것은 브랜치를 이동하는 것이 아니라 특정 파일만 변경하는 것이다. footer 브랜치에는 feature.txt가 존재하지 않았으나 feature 브랜치의 feature.txt를 가져와서 footer 브랜치에 복사하였다. 

브랜치 자체도 결국 특정 커밋을 가리키는 포인터이므로, 브랜치명 대신 커밋 해시를 넣어도 같은 원리로 동작한다. 브랜치명이나 커밋 해시를 지정하지 않을 경우 현재 브랜치에서 마지막으로 커밋된 상태로 파일을 되돌린다. 존재하지 않는 파일을 가져오거나 삭제 또는 수정된 파일을 최신 커밋 상태로 복구하는 동작이다.

$ git checkout 브랜치명 -- 파일명
$ git checkout 커밋해시 -- 파일명
$ git checkout -- 파일명  # 현재 브랜치에서 마지막으로 커밋된 상태로 파일을 되돌림

 

이전 브랜치로 체크아웃

새로운 브랜치가 아닌 이전 브랜치로 이동하려면 대시(-) 기호를 사용하면 된다.

$ git checkout -

 

브랜치 생성과 이동

브랜치 생성과 이동 명령을 따로 두 번씩 입력하는 것은 불편하다. 깃은 브랜치 생성과 이동 명령을 한 번에 처리하는 b 옵션을 제공한다.

$ git checkout -b 브랜치이름

 

브랜치 공간

브랜치 로그

로그를 출력할 때 브랜치 흐름도 같이 보려면 graph 옵션을 사용한다. all 옵션을 함께 사용하면 모든 로그를 출력한다.

$ git log --graph  # 현재 브랜치를 기준으로 커밋 그래프 표시
$ git log --graph --all  # 저장소의 모든 브랜치의 커밋 그래프 표시

 

more 옵션으로 출력될 커밋 개수를 제한할 수 있다.

$ git show-branch --more=5