브랜치
이력을 갈라 따로 이어가는 한 줄기입니다. 갈라 두면 원래 줄기는 그대로 둔 채 새 기록을 쌓을 수 있습니다. 갈라진 두 줄기는 나중에 다시 하나로 합칠 수 있습니다.
상세
문서를 고칠 때 원본은 그대로 두고 사본을 하나 떠서 사본에만 손을 대는 일을 떠올려 보십시오. 원본을 보는 사람은 아무 영향을 받지 않고, 사본에서 하던 일이 마음에 들면 그때 원본에 옮겨 적습니다. 브랜치는 갈라지기 전의 이력을 원래 줄기와 함께 갖습니다. 나중에 다시 하나로 잇는 일은 병합이라고 부릅니다.
브랜치는 이력의 한 줄기이고, 그 줄기의 끝을 가리키는 이름입니다. 줄기는 앞뒤로 이어진 변경 기록의 나열입니다. 그 줄기에 새 기록을 쌓으면 이름이 가리키는 자리가 앞으로 옮겨갑니다. 이름은 붙박이가 아니라 따라 움직입니다.
줄기가 갈라지는 순간 브랜치가 생깁니다. 갈라진 두 줄기는 갈라지기 전까지의 이력을 함께 갖습니다. 그 뒤로는 각자 자기 기록만 쌓습니다. 갈라진 줄기를 다시 하나로 잇는 일은 병합이라고 부릅니다.
flowchart TD
B1[기록 하나] --> B2[기록 둘]
B2 --> C1[기록 셋]
B2 --> D1[기록 넷]
N1(("이름 가")) -.가리킨다.-> C1
N2(("이름 나")) -.가리킨다.-> D1
이력의 한 시점에 붙이는 이름도 있습니다. 태그가 그것입니다. 태그는 붙인 자리에 머물러 있습니다. 브랜치는 새 기록이 쌓일 때마다 앞으로 옮겨간다는 점에서 갈립니다.
배경
새 기능을 만드는 일과 이미 내보낸 것을 손보는 일이 같은 줄기 위에서 겹치면 서로를 밟습니다. 절반쯤 고쳐 놓은 상태 위에 급한 수정을 얹으면, 내보낼 수 있는 상태가 어디였는지 아무도 못 짚습니다. 여럿이 한 줄기에만 기록을 쌓을 때도 같은 일이 벌어집니다. 남이 끝내지 않은 일이 내 작업에 섞여 들어옵니다.
그래서 이력을 한 줄로만 두지 않고 갈라 둘 필요가 생겼습니다. 갈라 두면 한쪽은 내보낼 수 있는 상태로 남기고 다른 쪽에서만 손을 댈 수 있습니다. 갈라 놓은 것을 언제 도로 합칠지는 합치는 쪽이 정합니다. 갈라 두는 일 자체가 합치는 일을 미뤄 두는 방식이기도 합니다.
갈라져 나온 한 줄기를 나무의 가지에 빗대어 브랜치라고 부릅니다. 갈라지기 전의 본줄기를 트렁크 라고 부르는 도구가 있는 것도 같은 비유에서 옵니다.
갈래
무엇을 기준으로 갈리는지가 셋입니다. 얼마나 오래 두고 쓰느냐, 그 이름을 누가 옮기느냐, 이름이 어디에 붙느냐입니다.
장수 브랜치와 토픽 브랜치
Git 공식 문서(Pro Git)는 늘 열어 둔 브랜치를 여럿 두고 개발 주기의 단계마다 나눠 쓰는 흐름을
적습니다. 그런 흐름의 하나로, 많은 Git 개발자가 완전히 안정된 코드만 master 에 두기도 한다고
적습니다. 이미 릴리스됐거나 릴리스될 코드만 두는 경우일 수도 있다고 덧붙입니다. 그와 나란한
develop 이나 next 라는 브랜치에서 작업하거나 안정성을 시험하고, 안정된 상태가 되면 master
로 병합합니다. 같은 문서는 이 브랜치가 언제나 안정된 것은 아니라고 덧붙입니다.
같은 문서는 토픽 브랜치를 하나의 기능이나 그와 관련된 작업 하나를 위해 만들어 쓰는, 수명이 짧은 브랜치라고 적습니다. 토픽 브랜치는 프로젝트 규모를 가리지 않고 쓸모가 있다고 적습니다. 축은 수명입니다. 한쪽은 개발 주기 내내 열려 있고 다른 쪽은 일이 끝나면 사라집니다.
원격 추적 브랜치
Git 공식 문서는 원격 추적 브랜치를 원격 저장소에 있는 브랜치의 상태를 가리키는 참조라고 적습니다. 로컬에 있는 참조인데 사람이 옮길 수는 없습니다. 네트워크 통신이 일어날 때마다 도구가 대신 옮겨 준다고 적습니다. 마지막으로 접속했을 때 원격의 브랜치가 어디에 있었는지를 알려 주는 북마크로 생각하라고 적습니다.
이름은 <원격이름>/<브랜치이름> 꼴입니다. 축은 누가 이름을 옮기느냐입니다. 내가 커밋을 쌓아
옮기는 브랜치가 있고, 페치나 푸시 같은 네트워크 통신이 대신 옮겨 주는 브랜치가 있습니다.
이름 붙은 브랜치
Mercurial 공식 위키는 브랜치에 이름을 붙이는 방식을 적습니다. 이름은 변경집합이 가진 속성으로
붙습니다. 이름을 따로 정하지 않으면 default 라는 이름이 붙는다고 적습니다. 같은 문서는 개발의
줄기가 갈라지면 브랜치가 생긴다고 적고, 갈라진 줄기를 기존 줄기에 합치는 일을 병합이라고
부릅니다.
이름이 기록 자신의 속성으로 붙는다는 점이 앞의 둘과 갈립니다. Git 공식 문서가 적는 브랜치는 기록 바깥에 따로 있는 파일 하나이고, 그 파일이 기록을 가리킵니다. 축은 이름이 붙는 자리입니다. 기록 안에 적히면 그 기록은 어느 브랜치에서 만들어졌는지를 스스로 들고 다닙니다.
예시
브랜치를 만드는 실물은 도구마다 다릅니다. 한쪽은 포인터 하나를 새로 쓰고, 다른 쪽은 저장소 안에서 경로를 복사합니다.
Git
$ git branch testing
이 명령은 지금 있는 자리의 커밋을 가리키는 새 포인터를 만듭니다. Git 공식 문서는 Git 의 브랜치가 실제로는 그 브랜치가 가리키는 커밋의 40자 SHA-1(Secure Hash Algorithm 1) 체크섬을 담은 단순한 파일이라고 적습니다. 그래서 브랜치를 새로 만드는 일은 파일에 41바이트를 쓰는 일과 다르지 않습니다. 40자에 줄바꿈 하나를 더한 값입니다. 같은 문서는 이 때문에 브랜치를 만들고 없애는 값이 싸다고 적습니다.
같은 문서는 기본 브랜치 이름 master 가 특별한 브랜치가 아니라고 적습니다. 다른 브랜치와 똑같은
것입니다. 거의 모든 저장소에 그 이름이 있는 이유는 git init 이 기본으로 만들고 대부분 굳이 바꾸지
않기 때문이라고 적습니다.
Subversion
$ svn copy http://svn.example.com/repos/calc/trunk \
http://svn.example.com/repos/calc/branches/my-calc-branch \
-m "Creating a private branch of /calc/trunk."
Committed revision 341.
$
Subversion 공식 문서(SVN Book)는 저장소 안에서 프로젝트 트리를 복사해 브랜치를 만든다고 적습니다.
trunk 아래에 있던 것이 branches/my-calc-branch 라는 경로로 복사됩니다. 명령의 결과로 남는 것은
새 리비전 하나입니다. 위 출력의 341 이 그 번호입니다. 브랜치가 포인터가 아니라 저장소 안의 경로로
존재한다는 점이 앞의 것과 갈립니다.
관련 항목
브랜치의 하위 종류
장수 브랜치 · 토픽 브랜치 · 원격 추적 브랜치 · 이름 붙은 브랜치
브랜치 개념을 구현하는 버전관리 도구
버전관리 · Git · Subversion · Mercurial
이력의 단위
커밋을 식별하는 값
갈라지고 합치기
병합 · 병합 충돌 · 리베이스 · 체크아웃 · HEAD · 트렁크
원격과 주고받기
원격 저장소 · 네트워크 · 페치 · 푸시 · 풀 · 풀 리퀘스트 · 포크
브랜치를 굴리는 방식
다른 이름: branch · branches · 가지