Branch

나뭇가지를 의미하는 Branch는 버전을 여러 흐름으로 나누어 관리하는 방법이다.

Branch의 필요성

  • 만약 브랜치가 없다면?

a와 b가 어느정도 완성된 상태의 프로젝트에 몇 가지 기능을 추가하고자 한다.

코드를 통째로 복사하여 각각 기능을 만들 것이고, 이 과정에서 파일을 추가하고 수정하고 삭제할 것이다. 둘이 작업을 모두 마치면 각자의 작업을 하나로 합칠 것인데 이때 어쩔 수 없이 a와 b는 각자가 수정한 코드를 하나하나 대조해봐야 한다. 같은 코드를 다르게 수정한 부분도 있을 것인데 이를 일일이 대조하고 합칠 코드를 판단하는 것은 너무나도 번거로운 일이다.

이러한 문제를 브랜치로 해결할 수 있다. 브랜치는 버전의 분기이다. 작업을 분기하고 싶을 때 브랜치를 나누면 된다.

브랜치를 나눈다 -> 각자의 브랜치에서 작업한다 -> (필요한 경우) 나눈 브랜치를 합친다

a와 b는 코드를 통째로 복사하지 않고 각각의 브랜치를 나눈다. 이제 각자의 브랜치에서 작업하고 하나로 합친다. 그러면 a와 b의 작업은 자동으로 하나로 통합된다. 이때 같은 코드를 다르게 수정한 부분만 살펴보면 된다.

브랜치 나누기

git branch foo // foo라는 브랜치를 만든다

깃이 제공하는 가장 최초의 브랜치를 main(master) 브랜치라고 한다.

main 브랜치에 커밋을 세 개 만들었다고 가정하자. master의 최신 커밋에 foo라는 브랜치를 만들고 foo 브랜치에 커밋을 두 개 추가해보자.

여기서 주목할 점은 main 브랜치 입장에서는 커밋이 세 개밖에 없다는 점이다. 반면 foo 브랜치 입장에서는 커밋이 다섯 개 있다.

master 브랜치에 커밋을 한 개 더 쌓은 후 가장 최신 커밋에서 bar라는 새로운 브랜치를 만들고, bar에 두 개의 커밋을 추가해 보자.

그러면 master 브랜치에는 4개의 커밋이, foo 브랜치에는 5개의 커밋이, bar 브랜치에는 6개의 커밋이 쌓이게 된다.

여기서 알아야 할 개념이 HEAD체크아웃이다.

  • HEAD는 기본적으로 현재 작업 중인 브랜치의 최신 커밋을 가리키는 표시이다. 브랜치를 나누고 합치는 과정에서 HEAD의 위치를 자유자재로 바꿀 수 있다.

  • 체크아웃이란 특정 브랜치에서 작업할 수 있도록 작업 환경을 바꾸는 것을 의미한다. 특정 브랜치로 체크아웃하게 되면 HEAD의 위치가 해당 브랜치의 최신 커밋을 가리키고, 작업 디렉터리는 체크아웃한 브랜치의 모습으로 바뀌게 된다.

git checkout foo // foo 브랜치로 체크아웃
git checkout -b <브랜치> // 브랜치 만듦과 동시에 체크아웃

브랜치의 이름

  • 새로운 기능을 개발하기 위한 브랜치 이름 'feature/<새기능>'

  • 릴리스를 준비하기 위한 브랜치 이름 'release/<릴리스 번호>'

  • 급하게 수정하기 위한 브랜치 이름 'hotfix/<수정사항>'

브랜치 병합하기

브랜치를 하나로 통합하는 것을 merge라고 한다.

위 예시는 foo 브랜치를 master 브랜치로 병합하는 그림이다. master 브랜치는 foo 브랜치와 같아진다. foo 브랜치가 master 브랜치에서 뻗아나온 시점부터 병합되는 순간까지 master 브랜치에는 아무 변화가 없었기 때문에 빠르게 merge된다. 이러한 기법을 빨리 감기 병합(fast-forward merge)라고 한다.

foo 브랜치를 master 브랜치에 병합하고 싶다면 master 브랜치로 체크아웃한 뒤

git merge foo

만약 충돌이 일어난다면 어떤 브랜치의 내용을 최종적으로 반영할 지 선택 후 충돌이 발생한 파일을 스테이지에 추가

병합 이후 브랜치에 남은 작업이 없다면 해당 브랜치를 삭제하는 것이 좋다.

foo 브랜치를 삭제하고 싶다면 foo가 아닌 브랜치로 체크아웃한 뒤

git branch -d foo

git branch 명령어로 브랜치 목록을 확인하면 삭제한 것을 확인할 수 있다.

bar 브랜치도 병합을 해보자. 그런데 foo 브랜치를 병합하니 bar 브랜치에 없는 커밋이 master 브랜치에 있다. 이때는 새로운 커밋이 생성된다.

bar 브랜치의 커밋 4만 master 브랜치로 병합

이렇게 foo 브랜치와 bar 브랜치를 모두 master 브랜치에 병합하면

bar 브랜치의 커밋 5, 6을 master 브랜치로 병합

충돌 해결하기

충돌이란 병합하려는 두 브랜치가 서로 같은 내용을 다르게 수정한 상황을 의미한다. 이때 최종적으로 어떤 브랜치의 내용을 반영할지 직접 선택해야 한다.

<<<<<<< HEAD
master (현재 브랜치 내용)
======
foo (foo 브랜치 내용)
>>>>>>> foo

====== 기호를 기준으로 윗부분은 HEAD가 가리키는, 즉 현재 체크아웃한 브랜치의 내용이 적혀있고, 아랫부분은 병합하려는 브랜치, 즉 foo 브랜치의 내용이 적혀있다.

브랜치 재배치하기

브랜치의 재배치는 rebase라고 한다.

master 브랜치에서 foo 브랜치를 만들고 체크아웃한 뒤 foo 브랜치에 커밋을 쌓는다. master 브랜치로 체크아웃한 뒤 master 브랜치에도 커밋을 쌓는다. 이때 foo 브랜치를 master 브랜치로 재배치하면 master 브랜치의 마지막 커밋으로 기준점이 이동된다. 이처럼 현재 브랜치의 내역을 대상 브랜치의 최신 버전 다음으로 배치하는 기능이다.

foo 브랜치를 master 브랜치로 재배치하고 싶다면, foo 브랜치로 체크아웃한 뒤

git rebase master

참고 문헌

  • 강민철. 『모두의 깃 & 깃허브』. 길벗, 2022.

Last updated