1. Branch의 개념
소프트웨어를 개발할 때에 개발자들은 동일한 소스코드를 함께 공유하고 다룬다.
동일한 소스코드 위에서 어떤 개발자는 버그를 수정하고, 다른 개발자는 새 기능을 추가한다.
이와 같이 여러 사람이 동일한 소스코드를 기반으로 서로 다른 작업을 할 때엔 서로 다른 버전의 코드가 만들어질 수밖에 없다.
이럴 때, 여러 개발자들이 동시에 다양한 작업을 할 수 있게 만들어 주는 기능이 바로 '브랜치'이다.
각자 독립적인 작업 영역 안에서 마음대로 소스코드를 변경할 수 있고, 후에 원래의 버전과 비교하여 하나의 새로운 버전으로 만들어 낼 수 있다.
1) 다른 브랜치의 영향을 받지 않기 떄문에, 여러 작업을 동시에 진행할 수 있다.
2) 다른 브랜치와 병합(Merge)함으로써, 작업한 내용을 다시 새로운 하나의 브랜치로 모을 수 있다.
2. master 브랜치
저장소를 처음 만들면, Git은 'master'라는 이름의 브랜치를 기본적으로 만들어 둔다.
이 새로운 저장소에 새로운 파일을 추가한다거나 추가한 파일의 내용을 변경하여 그 내용을 저장하는 것은 모두
'master'라는 이름의 브랜치를 통해 처리할 수 있는 일이 된다.
또 다른 새로운 브랜치를 만들어 '이제 이 브랜치를 사용할 것!'이라고 선언(체크아웃)하지 않는 이상, 이때의 모든 작업은 'master'브랜치에서 이루어진다.
3. Branch 만들기
Git에는 자유롭게 브랜치를 만들 수 있는데,
이것을 효과적으로 관리하려면, 브랜치 이름의 규칙, 어떤 상황에서 만들지, 어느 시점에 통합할 것인지를 정하는 게 좋다.
<우리가 만들 수 있는 브랜치의 종류>
1) 통합 브랜치(Integration Branch)
언제든지 배포할 수 있는 버전을 만들 수 있어야 하는 브랜치이다.
그렇기에 늘 안정적인 상태를 유지하는 것이 중요하고, 여기서 '안정적인 상태'란 모든 기능이 정상적으로 동작하는 상태를 의미한다.
일반적으로 저장소를 처음 만들었을 때에 생기는 'master'브랜치를 통합 브랜치로 사용한다.
만약 이 애플리케이션에 어떤 문제가 발견되어 그 문제를 수정한다던지 새로운 기능을 추가해야 한다던지 해야 할 때,
바로 '토픽 브랜치'를 만들 수 있다.
처음에는 보통 통합 브랜치에서 토픽 브랜치를 만들어 낸다.
2) 토픽 브랜치(Topic Branch)
기능 추가나 버그 수정과 같은 단위 작업을 위한 브랜치이다.
여러 개의 작업을 동시에 진행할 때에는, 그 수만큼 토픽 브랜치를 생성할 수 있다.
토픽 브랜치는 보통 통합 브랜치로부터 만들고, 토픽에서 특정 작업이 완료되면 다시 통합에 병합하는 방식으로 진행된다.
이러한 토픽 브랜치는 '피처 브랜치(Feature branch)'라고 부르기도 한다.
4. Branch 전환하기
Git에서는 항상 작업할 브랜치를 미리 선택해야 한다.
처음에 Git을 설치하게 되면 'master'브랜치가 선택되어 있다.
현재 선택된 브랜치가 아닌 다른 브랜치에서 작업하고 싶을 때에는, '체크아웃'명령어를 실행하여 원하는 브랜치로 전환할 수 있다.
체크아웃을 실행하면 우선 브랜치 안에 있는 마지막 커밋 내용이 작업 트리에 펼쳐진다.
브랜치가 전환 되었으므로 이 후에 실행한 커밋은 전환한 브랜치에 추가된다.
1) HEAD
'HEAD'란 현재 사용 중인 브랜치의 선두 부분을 나타내는 이름이다.
기본적으로는 'master'의 선두 부분을 나타내는데, 'HEAD'를 이동하면, 사용하는 브랜치가 변경된다.
커밋을 지정할 때, '~'와 '^'를 사용하여 현재 커밋으로부터 특정 커밋의 위치를 가리킬 수 있는데,
'HEAD' 뒤에 '~'와 숫자를 붙여 몇 세대 앞의 커밋을 가리킬 수 있고,
'^'은 브랜치 병합에서 원본이 여럿 있는 경우 몇번째 원본인지를 지정할 수 있다.
2) stash
커밋하지 않은 변경 내용이나 새롭게 추가한 파일이 인덱스와 작업 트리에 남아있는 채로 다른 브랜치로 전환하면,
그 변경 내용은 기존 브랜치가 아닌 전환된 브랜치에서 커밋할 수 있다.
단, 커밋 가능한 변경 내용 중에 전환된 브랜치에서도 한 차례 변경이 되어 있는 경우에는 체크아웃에 실패할 수 있다.
이 경우 이전 브랜치에서 커밋하지 않은 변경 내용을 커밋하거나,
stash를 이용해 일시적으로 변경 내용을 다른 곳에 저장하여 충돌을 피하게 한 뒤에 체크아웃을 해야 한다.
stash란, 파일의 변경 내용을 일시적으로 기록해두는 영역이다.
stash를 사용하여 작업 트리와 인덱스 내에서 아직 커밋하지 않은 변경을 일시적으로 저장해 둘 수 있다.
이 stash에 저장된 변경 내용은 나중에 다시 불러와 원래의 브랜치나 다른 브랜치에 커밋할 수 있다.
5. 브랜치 통합하기
작업이 완료된 토픽 브랜치는 최종적으로 통합 브랜치에 병합된다.
브랜치 통합에는 merge와 rebase를 사용하는 2가지 종류의 방법이 있다.
어느 쪽을 사용하느냐에 따라 통합 후의 브랜치의 이력이 크게 달라진다.
1) merge
merge를 사용하면, 여러 개의 브랜치를 하나로 모을 수 있다.
예를 들어, 아래 그림과 같이 'master'에서 분기하는 'bugfix'라는 브랜치가 있다고 가정해보자.
이 'bugfix'브랜치를 'master'브랜치로 병합할 때,
'master'브랜치의 상태가 이전부터 변경되어 있지만 않으면 매우 쉽게 병합할 수 있다.
'bugfix'브랜치의 이력은 'master'의 이력을 모두 포함하고 있기에,
'master'를 단순 이동시키기만 해도 'bugfix'브랜치의 내용을 적용할 수 있다.
이를 'fast-forward(빨리 감기) 병합'이라고 부른다.
하지만 bugfix를 분기한 이후에도 master에 여러가지 변경 사항이 적용되는 경우엔?
이 경우에는 master의 변경 내용과 bugfix브랜치 내의 변경 내용을 하나로 통합할 필요가 있다.
따라서 양쪽의 변경을 가져온 'merge commit(병합 커밋)'을 실행하게 된다.
병합 완료 후, 통합 브랜치인 master로 통합된 이력이 아래 그림과 같이 생기게 된다.
* fast-forward가 가능한 경우라도 non fast-forward를 지정하여 아래 그림과 같이 만들어 낼 수도 있다.
non fast-forward를 실행하면, 브랜치가 그대로 남기 때문에 그 브랜치로 실행한 작업 확인 및 브랜치 관리 면에서 더 유용할 수 있다.
2) rebase
만약 non fast-forward를 가정한다고 하면,
우선 bugfix를 master로 'rebase'하면, bugfix의 이려이 masger 뒤로 이동하게 되므로, 그림과 같이 이력이 하나의 줄기로 이어지게 된다.
이 때 이동하는 커밋 X와 Y내에 포함되는 내용이 master의 커밋된 버전들과 충돌하는 부분이 생길 수 있다.
그 때는 각각의 커밋에서 발생한 충돌 내용을 수정할 필요가 있다.
rebase만 하면 아래 그림에서와 같이 master의 위치는 그대로 유지된다.
master의 위치를 변경하기 위해서는 master에서 bugfix를 fast-forward병합하면 된다.
3) merge VS rebase
통합 브랜치에 토픽 브랜치를 통합하고자 하는 목적은 같으나, 그 특징은 약간 다르다.
- merge : 변경 내용의 이력이 모두 그대로 남아 있기에, 이력이 복잡해짐
- rebase : 이력은 단순해지지만, 원래의 커밋 이력이 변경됨. 정확한 이력을 남겨야 할 필요가 있을 경우엔 사용 X
그러니
-토픽 브랜치에 통합 브랜치의 최신 코드를 적용할 경우엔 rebase
-통합 브랜치에 토픽 브랜치를 불러올 경우에는 우선 rebase한 후 merge
(아직 감이 잘 오지 않는다.......)
6. 토픽 브랜치와 통합 브랜치에서의 작업 흐름
'기타 딩가딩가 > Github' 카테고리의 다른 글
3] Branch (실습) (0) | 2020.03.09 |
---|---|
1] Git시작하기 (설치, 첫 commit / push / pull / clone) (0) | 2020.02.29 |